home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Just Call Me Internet
/
Just Call Me Internet.iso
/
prog
/
atari
/
m2
/
cat3src
/
cat
/
grin.i
< prev
next >
Wrap
Text File
|
1997-10-26
|
157KB
|
4,564 lines
IMPLEMENTATION MODULE grin;
(*==============================================================*
* Modul: CAT-Anzeigemodul, neue Version *
* Autor: Johannes Gttker-Schnetmann *
* erstellt am: 19.10.1991 *
* letzte nderung am: 06.01.1993 *
* Version: 1.0 *
* Interne Version: V#0010 *
*==============================================================*
Anzeigemodul, beruhend auf dem CatEditor. Msgs werden als readonly-Texte
angezeigt.
Die Strings fr Infozeile und Windowtitle werden schon in CatEdit
behandelt und gespeichert, deswegen mu das hier noch rausfliegen,
um keinen Platz zu verschwenden.
Probleme: Fensterposition, Datenstruktur evtl. verkleinern, siehe
Anmerkungen im Text;
*----------------------------------------------------------------------------
* 19.10.91 0001 JGS Erste Version
* 20.10.91 JGS .. the endless story
* 22.12.91 JGS Fensterlisten verbessert
* 23.12.91 JGS Funktionsumfang erweitert, Erkennung ob Msg in
* gewnschte Richtung verfgbar, Debugging
* 16.02.92 JGS Beginn Implementation der Infozeile
* 09.03.92 0002 JGS Anpassung an CatTypes
* 25.03.92 0003 JGS Neuer Windowdialog, normale Infozeile wird auch
* initialisiert
* 26.03.92 JGS Features erweitert 27./
* 01.04.92 JGS Flags setzen, auch ber einen Klick in die Box
* 02.04.92 0004 JGS Status bei persnlichen Msgs
* 03.04.92 JGS Gelesen-Bit automatisch setzen
* 04.04.92 JGS Letzte Gelesene Msg/erste graphische Positionsanzeige/
* ctrl zustzlich ffnet neues Fenster
* 06.04.92 0005 JGS Versuch, alle Aktionen in der Box unterzubringen:
* jetzt Popups..
* 08.06.92 0006 JGS Zur nchsten Gruppe mit neuen Nachrichten..
* 10.04.92 0007 JGS Antworten/Kommentieren ber untergeordnetes Modul
* 12.04.92 JGS Anpassung an neues handlePool, flexiblere Listen
* 16.04.92 0008 JGS Richtige Reihenfolge beim Gruppenwechsel
* 19.04.92 0009 JGS Suchen eingebaut
* 15.08.92 JGS Bugfix Rckwrts-suchen; Zuerst in Msg suchen, dann in Database
* 01.10.92 JGS Einige kleinere nderungen wg. neuer Datenbank
* 17.12.92 DS Einige Bugfixes und nderungen wegen Link zu MsgList
* 27.12.92 0010 JGS Flags werden jetzt direkt hier verwaltet, vorher in cat.m, popups
* 28.12.92 JGS gruppenbergreifende Kommentare
* 29.12.92 JGS Flagnderungen in allen sichtbaren Msgs
* 31.12.92 JGS Protokollunterstrzung, Baum "behandeln"
* 06.01.93 JGS <undo> bei Msgs, verbessertes Handling bei Fehlern
* 12.08.93 JGS Anzeige, ob Nachricht vom User oder Kommentar auf solche
* 30.09.93 JGS Suchen nach Usenet-Verkettung
*----------------------------------------------------------------------------
*)
(*-- MM2-Module ------------------------------------------------------------*)
FROM SYSTEM IMPORT ADDRESS, ADR, TSIZE, CALLSYS, CADR, ASSEMBLER;
FROM Storage IMPORT ALLOCATE, DEALLOCATE, AllAvail;
IMPORT Lists;
IMPORT GrafBase;
IMPORT BinOps;
IMPORT Strings;
IMPORT StrConv;
IMPORT Block;
FROM Characters IMPORT CR, LF;
(*-- Cat-Module ------------------------------------------------------------*)
FROM Void IMPORT v;
FROM UserInformation IMPORT UserBLK;
FROM Messages IMPORT SendState;
FROM GroupComment IMPORT PrepareIDnGroup, PrepareID;
IMPORT data;
IMPORT dataSys;
IMPORT CatEdit;
IMPORT EditTypes;
IMPORT MTE;
IMPORT VDIStandards;
IMPORT VDIUtil;
IMPORT MausTauschrsc;
IMPORT CatTypes;
IMPORT grinTools;
IMPORT handlePool;
IMPORT ZSearchDial;
IMPORT SearchHelp;
FROM SearchHelp IMPORT suchVar;
IMPORT ConfVars;
IMPORT msgList;
IMPORT Varnames;
IMPORT CatGlobal;
IMPORT WdwManager;
IMPORT ConvertDate;
IMPORT ListHelp;
IMPORT RectFuncs;
IMPORT GroupSelect;
IMPORT treeList;
IMPORT AssFuncs;
IMPORT GenderTest;
IMPORT WiederVorlage;
IMPORT Protokoll;
IMPORT Clip;
(*-- Magic-Lib -------------------------------------------------------------*)
IMPORT MagicStrings;
IMPORT MagicAES;
IMPORT MagicVDI;
IMPORT MagicDOS;
IMPORT MagicConvert;
(*-- Magic-Tools -----------------------------------------------------------*)
IMPORT mtArea;
IMPORT mtPopups;
IMPORT mtUtils;
IMPORT mtAlerts;
IMPORT mtAppl;
IMPORT WinDials;
CONST DEBUG = FALSE;
CONST oldInfoLine = TRUE;
(* Das mu natrlich noch eine der globalen Variablen im catuser.inf werden *)
CONST openBracket = '(';
closeBracket = ')';
spaceString = ' ';
colonString = ':';
rawInfoline = '.... ---------- '; (* oder auch lfitdkbuuv? *)
cMale = "Herr";
cFemale = "Frau";
CONST StateAnz = 9;
CONST escScan = 1C;
spaceScan = 71C;
nullScan = 160C;
pointScan = 161C;
oneScan = 155C;
twoScan = 156C;
threeScan = 157C;
fourScan = 152C;
fiveScan = 153C;
sixScan = 154C;
eightScan = 150C;
undoScan = 141C;
nScan = 61C;
zScan = 25C;
insertScan= 122C;
backspaceScan = 16C;
tabScan = 17C;
lScan = 46C; (* Gelesen-Flag *)
fScan = 41C; (* Gefunden-Flag *)
iScan = 27C; (* Interessant-Flag *)
tScan = 24C; (* Teillschen-Flag *)
dScan = 40C; (* Lschen-Flag *)
kScan = 45C; (* Kommentieren-Flag *)
bScan = 60C; (* Beantworten-Flag *)
cScan = 56C; (* Userflag 1 *)
xScan = 55C; (* Userflag 2 *)
vScan = 57C; (* Vererben-Flag *)
(* Zu jedem Fenster gehrt eine folgende Struktur: *)
TYPE oneWindowPtr = POINTER TO oneWindow;
TYPE headerInfoType = (headerNone, headerGruppe, headerFollowupTo,
headerID, headerKomZu,
headerBetreff, headerVon, headerSender, headerReplyTo,
headerName, headerAn,
headerMId, headerRId, headerMime, headerGate,
headerBox, headerStatus, headerKomAnz,
headerEmptyLine);
CONST maxStack = 1023;
TYPE viewHeaderMode = (vhNone, vhFull);
TYPE stackArrayType = ARRAY[0..maxStack] OF CARDINAL;
TYPE stackPointerType = POINTER TO stackArrayType;
TYPE oneWindow =
RECORD
win : INTEGER; (* Zugehriges Fenster *)
handle : handlePool.oneHandlePtr; (* Zeiger in die Datenbankhandleliste *)
mess : data.MessageType; (* Alle Daten zu einer Message *)
isEnriched: BOOLEAN; (* Aktuelle Nachricht ist text/enriched *)
nextMsg : grinNextMessProc; (* Kann von aufrufender Prozedur bei grinOpenMessage bergeben werden *)
listHdl : LONGCARD; (* " *)
info,
title : CatTypes.String255;
number : INTEGER;
inObjcDraw : BOOLEAN; (* Es wird gerade ein einzelnes Objekt neu gezeichnet *)
font,
fontSize : INTEGER;
lastPos : CARDINAL; (* Fr <home> in der Kommentarverkettung *)
undoPos,
undoGroup,
undoTreeRoot : CARDINAL; (* Fr <undo> bei Msgs *)
lastLine : headerInfoType;
mode : openMode;
readchange : BOOLEAN; (* hat der user etwas am Gelesen-Flag gemacht? *)
isLocked : BOOLEAN; (* Fenster gelockt, da Suche luft oder hnliches *)
inEvent : BOOLEAN; (* Fenster behandelt gerade einen Click-Event *)
(* Fr's Baumlaufen: *)
treeMode : BOOLEAN;
idx : CARDINAL;
stack : stackPointerType;
stackPointer : CARDINAL;
(* Fr SuppressRef *)
originalText : ADDRESS;
refSuppressed: BOOLEAN;
(* Fr Anzeige: *)
viewHeader : viewHeaderMode;
viewBuff : ADDRESS;
viewLen : LONGCARD;
viewAllocated: BOOLEAN;
(* Fr Drag&Drop: *)
ddObjc : INTEGER;
END;
(* Um Platz zu sparen, mte in Zukunft mglicherweise in data.MessageType
* eine flexible Verwaltung der 4 langen Strings erfolgen; auerdem knnte
* man dann auch <info> und <title> flexibel gestalten
*)
TYPE NumSet = SET OF [0..255];
VAR grinNums : NumSet;
globalNumber : INTEGER;
TYPE dirType = (dPrevMess, dNextMess, dUpMess, dDownMess, dLeftMess, dRightMess, dReturn, dJump, dGroupJump, dNone);
VAR windows : Lists.List; (* Liste der offenen Fenster/Messages *)
VAR infoAdr,
flagPop,
addInfo : POINTER TO ARRAY[0..MAX(CARDINAL)] OF MagicAES.OBJECT;
RefIdUnterdruecken : BOOLEAN;
restrictedMoves : BOOLEAN;
spacePaging : BOOLEAN;
isInSearch : BOOLEAN;
autoNextGroup : BOOLEAN;
autoNextPing : BOOLEAN;
PROCEDURE stopSearch():BOOLEAN;
VAR char, scan : CHAR; kstate : BITSET;
BEGIN
RETURN VDIUtil.isKey(kstate, scan, char) & (char = 33C);
END stopSearch;
TYPE intPtr = POINTER TO INTEGER;
(*$A+,Z-*)
PROCEDURE FindWinCond(e, i : ADDRESS):BOOLEAN;
(* Abbruchprozedur, wie in <Lists> gefordert *)
BEGIN
RETURN oneWindowPtr(e)^.win = intPtr(i)^
END FindWinCond;
(*$A=,Z=*)
(*--- Zugriff auf die Datenbank -------------*)
CONST cTo = "To: ";
cFrom = "From: ";
cGroup = "Group: ";
cNewsgroups = "Newsgroups: ";
cSubject = "Subject: ";
cMausId = "Maus-ID: ";
cMausRef = "Maus-Ref: ";
cMessageID = "Message-ID: ";
cReferences = "References: ";
cDate = "Date: ";
cStatusDate = "State: ";
cFollowup = "Followup-To: ";
cReply = "Reply-To: ";
cSender = "Sender: ";
cOrganization = "Organization: ";
cGateway = "Gateway: ";
cMime = "MIME: ";
cDashs = '------------------------------------------------------------------------' + CR+LF+0C;
cLineEnd = CR+LF;
cTAB = 011C;
cContent = 'Content-Type:';
cTextEnriched = 'text/enriched';
cCharset = 'charset=';
cIso = 'ISO-8859-1';
PROCEDURE CharInStr (REF pattern: ARRAY OF CHAR;
REF str: ARRAY OF CHAR): INTEGER;
VAR p, l, highP, i : INTEGER;
BEGIN
p := 0;
l := LENGTH (str);
highP := LENGTH (pattern)-1;
WHILE p < l DO
FOR i := 0 TO highP DO
IF str[p] = pattern [i]
THEN
RETURN p;
END;
END;
INC (p);
END;
RETURN -1;
END CharInStr;
PROCEDURE BuildId (str: CatTypes.Str255Ptr; VAR id: ARRAY OF CHAR);
VAR quote: BOOLEAN;
BEGIN
MagicStrings.Assign ("", id);
quote := FALSE;
IF (str # NIL) & (str^[0] # 0C)
THEN
IF (str^[0] # '<')
THEN
quote := TRUE;
END;
IF quote
THEN
MagicStrings.Append ("<", id);
END;
MagicStrings.Append (str^, id);
IF quote
THEN
MagicStrings.Append (">", id);
END;
END;
END BuildId;
PROCEDURE BuildName (str1, str2: CatTypes.Str255Ptr; VAR name: ARRAY OF CHAR);
VAR quote: BOOLEAN;
BEGIN
MagicStrings.Assign ("", name);
quote := FALSE;
IF (str2 # NIL) & (str2^[0] # 0C)
THEN
IF CharInStr ('!()<>@,;:\".[]', str2^) >= 0
THEN
quote := CharInStr ("()<>", str2^) < 0;
ELSE
quote := FALSE;
END;
IF quote
THEN
quote := str2^[0] # '"';
END;
IF quote
THEN
MagicStrings.Append ('"', name);
END;
MagicStrings.Append (str2^, name);
IF quote
THEN
MagicStrings.Append ('"', name);
END;
END;
IF str1 # NIL
THEN
IF (str2 # NIL)
& (CharInStr ("()<>", str2^) < 0)
THEN
quote := (str1^[0] # '<') & (str1^[0] # '(');
IF LENGTH (name) > 0
THEN
MagicStrings.Append (" ", name);
ELSE
quote := FALSE;
END;
IF quote
THEN
MagicStrings.Append ("<", name);
END;
MagicStrings.Append (str1^, name);
IF quote
THEN
MagicStrings.Append (">", name);
END;
ELSIF str2 = NIL
THEN
MagicStrings.Append (str1^, name);
END;
END;
END BuildName;
PROCEDURE GetLength (str: CatTypes.Str255Ptr; REF lineId: ARRAY OF CHAR): CARDINAL;
BEGIN
IF str = NIL THEN RETURN 0 END;
IF str^[0] = 0C THEN RETURN 0 END;
RETURN LENGTH (lineId) + LENGTH (str^);
END GetLength;
PROCEDURE CopyItem (buff: CatTypes.LargeTextPtr; str: CatTypes.Str255Ptr;
REF lineId: ARRAY OF CHAR; VAR pos: LONGCARD);
VAR adr: ADDRESS;
BEGIN
IF str = NIL THEN RETURN END;
IF str^[0] = 0C THEN RETURN END;
adr := buff + ADDRESS(pos);
IF LENGTH (lineId) > 0
THEN
Block.Copy (CADR(lineId), LENGTH (lineId), buff+ADDRESS(pos));
INC (pos, LENGTH (lineId));
END;
Block.Copy (str, LENGTH (str^), buff+ADDRESS(pos));
INC (pos, LENGTH (str^));
Block.Copy (CADR(cLineEnd), LENGTH(cLineEnd), buff+ADDRESS(pos));
INC (pos, LENGTH(cLineEnd));
END CopyItem;
PROCEDURE ParseMime (orgText: CatTypes.BigTextPtr; newText: CatTypes.BigTextPtr;
VAR textLen: CARDINAL);
VAR idx, destIdx : CARDINAL;
ch : CHAR;
i,
newLineCnt,
paramcount,
excerptCount,
noFill : INTEGER;
token : CatTypes.String255;
found : BOOLEAN; (* einzelne '-'-Zeile gefunden *)
excerptSet : BOOLEAN;
BEGIN
(* Simpel-Parser basierend auf RFC 1563
*)
paramcount := 0;
excerptCount := 0;
excerptSet := FALSE;
noFill := 0;
newLineCnt := 0;
idx := 0;
destIdx := 0;
(* Erweiterung fr MausNet: *)
(* Erstmal nach LF'-'LF suchen, in der DB steht eh nur LF als Zeilenende drin *)
found := FALSE;
WHILE (idx < textLen) & ~found DO
IF (orgText^[idx] = '-') & (orgText^[idx+1] = LF)
THEN
IF (idx = 0) OR (orgText^[idx-1] = LF)
THEN
found := TRUE;
INC (idx, 2);
END;
ELSE
INC (idx);
END;
END;
IF ~found
THEN
idx := 0;
END;
(* Ende der Erweiterung fr MausNet *)
WHILE idx < textLen DO
ch := orgText^[idx];
IF ch = '<'
THEN
IF newLineCnt = 1
THEN
newText^[destIdx] := ' ';
INC (destIdx);
END;
newLineCnt := 0;
INC (idx);
ch := orgText^[idx];
IF ch = '<'
THEN
IF paramcount <= 0
THEN
newText^[destIdx] := ch;
INC (destIdx);
END;
ELSE
i := 0;
WHILE (idx < textLen) & (ch # '>') DO
IF i < SIZE (token)
THEN
token[i] := CAP(ch);
INC (i);
END;
INC (idx);
ch := orgText^[idx];
END;
token[i] := 0C;
IF Strings.StrEqual (token, "PARAM")
THEN
INC (paramcount);
ELSIF Strings.StrEqual (token, "EXCERPT")
THEN
INC (excerptCount);
excerptSet := TRUE;
ELSIF Strings.StrEqual (token, "BOLD")
OR Strings.StrEqual (token, "/BOLD")
THEN
newText^[destIdx] := '*';
INC(destIdx);
ELSIF Strings.StrEqual (token, "ITALIC")
OR Strings.StrEqual (token, "/ITALIC")
THEN
newText^[destIdx] := '/';
INC(destIdx);
ELSIF Strings.StrEqual (token, "UNDERLINE")
OR Strings.StrEqual (token, "/UNDERLINE")
THEN
newText^[destIdx] := '_';
INC(destIdx);
ELSIF Strings.StrEqual (token, "NOFILL")
THEN
INC (noFill);
ELSIF Strings.StrEqual (token, "/PARAM")
THEN
DEC (paramcount);
ELSIF Strings.StrEqual (token, "/EXCERPT")
THEN
DEC (excerptCount);
ELSIF Strings.StrEqual (token, "/NOFILL")
THEN
DEC (noFill);
END
END;
ELSE (* IF ch = '<' *)
IF paramcount > 0
THEN
ELSIF (ch = LF) & (noFill <= 0)
THEN
INC (newLineCnt);
IF newLineCnt > 1
THEN
newText^[destIdx] := ch;
INC(destIdx);
IF excerptCount > 0
THEN
FOR i := 1 TO excerptCount DO
newText^[destIdx] := ">";
INC(destIdx);
END;
excerptSet := FALSE;
END;
END;
ELSE
IF newLineCnt = 1
THEN
newText^[destIdx] := ' ';
INC(destIdx);
END;
newLineCnt := 0;
IF excerptSet
THEN
FOR i := 1 TO excerptCount DO
newText^[destIdx] := ">";
INC(destIdx);
END;
excerptSet := FALSE;
END;
newText^[destIdx] := ch;
INC(destIdx);
END;
END;
INC (idx);
END; (* WHILE *)
newText^[destIdx] := LF;
INC (destIdx);
newText^[destIdx] := 0C;
textLen := destIdx; (* neue Lnge zuweisen *)
END ParseMime;
PROCEDURE GetStatusText (state: CHAR; VAR status: ARRAY OF CHAR);
BEGIN
CASE state OF
'N': MagicStrings.Assign ('Nicht gelesen', status); |
'Z': MagicStrings.Assign ('Zurckgestellt', status); |
'B': MagicStrings.Assign ('Beantwortet', status); |
'G': MagicStrings.Assign ('Gelesen', status); |
'W': MagicStrings.Assign ('Weitergegeben', status); |
'M': MagicStrings.Assign ('Mausnet', status); |
'A': MagicStrings.Assign ('Angekommen', status); |
'Y': MagicStrings.Assign ('Gateway angekommen', status); |
'K': MagicStrings.Assign ('Kopiert', status); |
'T': MagicStrings.Assign ('Im MausTausch', status); |
ELSE
MagicStrings.Assign ('Unbekannter Status', status);
END;
END GetStatusText;
PROCEDURE GetOneMessage(ptr : oneWindowPtr; nr : CARDINAL):BOOLEAN;
(* den zugehrigen Typ auffllen *)
VAR z : CARDINAL;
uName,
gName : CatTypes.String255;
pos : LONGCARD;
cStart : INTEGER;
cEnd : INTEGER;
content : CatTypes.String255;
newText : CatTypes.BigTextPtr;
oldLen : CARDINAL;
BEGIN
data.ReadMessage(ptr^.handle^.Zugriff, nr, ptr^.mess);
IF data.error = data.noError
THEN
WITH ptr^ DO
IF mess.Text # NIL
THEN
isEnriched := FALSE;
(* Jetzt MIME-Parser anwerfen *)
IF mess.mime # NIL
THEN
(* Content-type extrahieren, mte eigentlich case-insensitiv sein *)
cStart := Strings.Pos (cContent, mess.mime^, 0);
IF cStart > 0
THEN
cStart := cStart + INTEGER(LENGTH(cContent));
cEnd := Strings.Pos (";", mess.mime^, cStart);
IF cEnd < 0
THEN
cEnd := INTEGER(LENGTH (mess.mime^));
END;
Strings.Copy (mess.mime^, cStart, cEnd - cStart, content, v.bool);
(* Fhrende Leerzeichen abschneiden *)
Strings.DelLeadingBlanks (content);
(* Content-type prfen *)
IF AssFuncs.StrIequal (cTextEnriched, content)
THEN
isEnriched := TRUE;
(* Text kopieren und parsen *)
oldLen := mess.textLen + 2048;
ALLOCATE (newText, oldLen);
IF newText # NIL
THEN
(* Wenn kein Speicher frei ist, dann zeigen wir
* das halt unverndert an
*)
ParseMime (mess.Text, newText, mess.textLen);
DEALLOCATE (mess.Text, 0);
mess.Text := newText;
(* Speicherblock fr newText noch anpassen *)
IF oldLen # mess.textLen
THEN
DEALLOCATE (mess.Text, oldLen - mess.textLen);
END;
END;
END;
END;
cStart := Strings.Pos (cCharset, mess.mime^, 0);
IF cStart > 0
THEN
cStart := cStart + INTEGER(LENGTH(cCharset));
cEnd := Strings.Pos (";", mess.mime^, cStart);
IF cEnd < 0
THEN
cEnd := INTEGER(LENGTH (mess.mime^));
END;
Strings.Copy (mess.mime^, cStart, cEnd - cStart, content, v.bool);
IF AssFuncs.StrIequal (cIso, content)
THEN
(* Umlaute wandeln *)
AssFuncs.WandleIso (mess.Text, mess.textLen);
END;
END;
END;
END;
END;
ptr^.refSuppressed := FALSE;
IF RefIdUnterdruecken & (ptr^.mess.up < dataSys.notSaved) &
(ptr^.mess.Text # NIL) &
(ptr^.mess.Text^[0] = '-') &
((ptr^.mess.fromOther) OR (ptr^.mess.KommentierteID[0] = 0C)) THEN
(* Also wenn kein Dateifehler aufgetreten ist, eine Verkettung hergestellt *)
(* wurde, in der ersten Zeile mglicherweise eine Verkettung steht aber keine *)
(* ID von der Maus geliefert wurde *)
(* Originalpointer merken *)
ptr^.originalText := ptr^.mess.Text;
ptr^.refSuppressed := TRUE;
WITH ptr^.mess DO
REPEAT
INC(Text);
DEC(textLen);
UNTIL (Text^[0] = LF) OR (textLen = 0);
(* Ende der Zeile suchen *)
WHILE (Text^[0] = LF) & (textLen > 0) DO
INC(Text);
DEC(textLen);
END;
END (* WITH *);
(* Zeilenende und evtl. noch ein paar Leerzeilen berspringen *)
END;
(* Jetzt viewBuffer aufbauen *)
(* Gre feststellen *)
WITH ptr^ DO
IF mess.Text # NIL
THEN
(* Und jetzt nachsehen, ob wir den Header anzeigen oder nicht *)
viewLen := 0;
IF viewHeader = vhFull
THEN
(* Alle Headerinformationen:
* To:
* From: "Dirk Steins" <dirk_steins@k2.maus.de>
* Newsgroups:
* Subject:
* Maus-ID:
* Maus-Ref:
* Message-ID: <..>
* References: <...>
* Date: englisches Datum
* Date: englisches Datum
* Followup-To:
* Reply-To:
* Organization: ...
* Gateway: ...
* Mime: ...
* Statusdatum: ...
*)
WITH mess DO
INC (viewLen, GetLength (Empfaenger, cTo));
BuildName (Absender, name, uName);
INC (viewLen, GetLength (ADR(uName), cFrom));
IF Gruppe # dataSys.private
THEN
GroupSelect.GroupName (Gruppe, gName);
INC (viewLen, GetLength (ADR(gName), cNewsgroups));
END;
INC (viewLen, GetLength (Betreff, cSubject));
INC (viewLen, GetLength (MailID, cMausId));
INC (viewLen, GetLength (ADR(KommentierteID), cMausRef));
INC (viewLen, GetLength (mid, cMessageID));
INC (viewLen, GetLength (rid, cReferences));
(* Datum vorlufig, mu noch umgewandelt werden *)
INC (viewLen, GetLength (ADR(Datum), cDate));
IF (Gruppe = dataSys.private)
& (EigeneNachricht)
THEN
GetStatusText (Status, uName);
MagicStrings.Append (' (', uName);
MagicStrings.Append (StatusDatum, uName);
MagicStrings.Append (' Uhr)', uName);
INC (viewLen, GetLength (ADR(uName), cStatusDate));
(*
INC (viewLen, GetLength (ADR(StatusDatum), cStatusDate));
*)
END;
INC (viewLen, GetLength (sender, cSender));
INC (viewLen, GetLength (replyTo, cReply));
INC (viewLen, GetLength (followupTo, cFollowup));
INC (viewLen, GetLength (box, cOrganization));
INC (viewLen, GetLength (gate, cGateway));
INC (viewLen, GetLength (mime, cMime));
INC (viewLen, LENGTH (cDashs)+4);
INC (viewLen, 40);
END;
END;
INC (viewLen, mess.textLen);
ALLOCATE (viewBuff, viewLen);
IF viewBuff = NIL
THEN
viewBuff := mess.Text;
viewLen := mess.textLen;
viewAllocated := FALSE;
ELSE
viewAllocated := TRUE;
(* Buffer alloziert, nun reinschreiben *)
pos := 0;
IF viewHeader = vhFull
THEN
WITH mess DO
(* Einzelne Items kopieren *)
CopyItem (viewBuff, Empfaenger, cTo, pos);
BuildName (Absender, name, uName);
CopyItem (viewBuff, ADR(uName), cFrom, pos);
CopyItem (viewBuff, sender, cSender, pos);
CopyItem (viewBuff, replyTo, cReply, pos);
IF Gruppe # dataSys.private
THEN
GroupSelect.GroupName (Gruppe, gName);
CopyItem (viewBuff, ADR(gName), cNewsgroups, pos);
END;
CopyItem (viewBuff, followupTo, cFollowup, pos);
CopyItem (viewBuff, Betreff, cSubject, pos);
CopyItem (viewBuff, MailID, cMausId, pos);
CopyItem (viewBuff, ADR(KommentierteID), cMausRef,pos);
BuildId (mid, uName);
CopyItem (viewBuff, ADR(uName), cMessageID, pos);
BuildId (rid, uName);
CopyItem (viewBuff, ADR(uName), cReferences, pos);
(* Datum vorlufig, mu noch umgewandelt werden *)
CopyItem (viewBuff, ADR(Datum), cDate, pos);
CopyItem (viewBuff, box, cOrganization, pos);
CopyItem (viewBuff, gate, cGateway, pos);
CopyItem (viewBuff, mime, cMime, pos);
IF (Gruppe = dataSys.private)
& (EigeneNachricht)
THEN
GetStatusText (Status, uName);
MagicStrings.Append (' (', uName);
MagicStrings.Append (StatusDatum, uName);
MagicStrings.Append (' Uhr)', uName);
CopyItem (viewBuff, ADR(uName), cStatusDate, pos);
END;
CopyItem (viewBuff, CADR(cDashs), "", pos);
END;
END;
(* Text kopieren *)
Block.Copy (mess.Text, mess.textLen, viewBuff + ADDRESS(pos));
INC (pos, mess.textLen);
viewLen := pos;
END;
END;
END;
END;
(*$? DEBUG:
IF data.error # data.noError
THEN
CASE data.error OF
data.notFound : MTE.numAlert (INTEGER(nr), "[3][Nachricht & |nicht gefunden.][[Abbruch]");
| data.IOError : MTE.numAlert (INTEGER(nr), "[3][I/O-Fehler bei|Nachricht &.][[Abbruch]");
| data.noMemErr : MTE.numAlert (INTEGER(nr), "[3][Nicht genug Speicher|bei Nachricht &.][[Abbruch]");
| data.crcError : MTE.numAlert (INTEGER(nr), "[3][CRC-Fehler bei|Nachricht &.][[Abbruch]");
| data.fileError: MTE.numAlert (INTEGER(nr), "[3][Datei-Fehler bei|Nachricht &.][[Abbruch]");
ELSE
END;
END;
*)
RETURN data.error = data.noError;
END GetOneMessage;
(*--- Fr das Drucken des Headers -------------------------------*)
PROCEDURE grinGetHeaderInfo (wdw : INTEGER; which : EditTypes.lineMode;
VAR s : ARRAY OF CHAR) : BOOLEAN;
(* Liefert eine Headerzeile zurck, und zwar entweder die erste
* oder die auf die zuletzt gelieferte folgende. Wenn keine Zeile
* mehr da ist, dann wird als Ergebnis FALSE zurckgegeben.
* Ebenso, wenn das Fenster gar kein Anzeigefenster ist
TYPE headerInfoType = (headerNone, headerGruppe, headerID, headerKomZu, headerBetreff,
headerVon, headerName, headerAn, headerBox, headerRId,
headerMId, headerStatus, headerKomAnz, headerEmptyLine);
*)
VAR ptr : oneWindowPtr;
PROCEDURE ReturnPtr(REF pre : ARRAY OF CHAR; REF str : CatTypes.String255):BOOLEAN;
(* String in s zusammenstellen *)
BEGIN
MagicStrings.Assign(pre, s);
IF str[0] # 0C THEN
MagicStrings.Append(str, s);
RETURN TRUE
ELSE
RETURN FALSE
END;
END ReturnPtr;
PROCEDURE comment():BOOLEAN;
BEGIN
IF ptr^.mess.KommentarAnzahl = 0 THEN
RETURN FALSE;
ELSE
IF ptr^.mess.KommentarAnzahl = 1 THEN
MagicStrings.Assign('Hierzu gibt es einen Kommentar', s);
ELSE
IF ptr^.mess.KommentarAnzahl < 100 THEN
MagicConvert.CardToStr(ptr^.mess.KommentarAnzahl, 1, s);
ELSE
MagicStrings.Assign('xx', s);
END;
MagicStrings.Insert('Hierzu gibt es ', s, 0);
MagicStrings.Append(' Kommentare', s);
END;
RETURN TRUE
END;
END comment;
BEGIN
IF handlePool.FindEntry(ADR(wdw), FindWinCond, windows, ptr) THEN
IF which = EditTypes.LFIRST THEN ptr^.lastLine := headerNone END;
LOOP
IF ptr^.lastLine = headerEmptyLine THEN
ptr^.lastLine := headerNone; RETURN FALSE
ELSE
INC(ptr^.lastLine);
CASE ptr^.lastLine OF
headerGruppe : GroupSelect.GroupName(ptr^.mess.Gruppe, s); MagicStrings.Insert('Gruppe: ', s, 0); RETURN TRUE;
|headerID : v.bool := ReturnPtr('ID: ', ptr^.mess.MailID^); RETURN TRUE
|headerKomZu : IF ReturnPtr('Kommentar zu ', ptr^.mess.KommentierteID) THEN RETURN TRUE END;
|headerBetreff : v.bool := ReturnPtr('Wg.: ', ptr^.mess.Betreff^); RETURN TRUE;
|headerVon : IF ReturnPtr('Von: ', ptr^.mess.Absender^) THEN
MagicStrings.Append(' (', s);
MagicStrings.Append(ptr^.mess.Datum, s);
MagicStrings.Append(')', s);
RETURN TRUE
END;
|headerName : IF ReturnPtr('Name: ', ptr^.mess.name^) THEN RETURN TRUE END;
|headerAn : IF ReturnPtr('An: ', ptr^.mess.Empfaenger^) THEN
IF (ptr^.mess.Gruppe = dataSys.private) &
ptr^.mess.EigeneNachricht
THEN
MagicStrings.Append(' (', s);
MagicStrings.Append(ptr^.mess.Datum, s);
MagicStrings.Append(')', s);
END;
RETURN TRUE
END;
|headerBox : IF ReturnPtr('Box: ', ptr^.mess.box^) THEN RETURN TRUE END;
|headerGate : IF ReturnPtr('Gate: ', ptr^.mess.gate^) THEN RETURN TRUE END;
|headerMime : IF ReturnPtr('MIME: ', ptr^.mess.mime^) THEN RETURN TRUE END;
|headerSender : IF ReturnPtr('Sender:', ptr^.mess.sender^) THEN RETURN TRUE END;
|headerReplyTo : IF ReturnPtr('Reply-To:', ptr^.mess.replyTo^) THEN RETURN TRUE END;
|headerFollowupTo : IF ReturnPtr('Followup-To:', ptr^.mess.followupTo^) THEN RETURN TRUE END;
|headerRId : IF ReturnPtr('RId: ', ptr^.mess.rid^) THEN RETURN TRUE END;
|headerMId : IF ReturnPtr('MId: ', ptr^.mess.mid^) THEN RETURN TRUE END;
|headerStatus : IF (ptr^.mess.Gruppe = dataSys.private) &
ptr^.mess.EigeneNachricht
THEN
GetStatusText (ptr^.mess.Status, s);
MagicStrings.Append(' (', s);
MagicStrings.Append (ptr^.mess.StatusDatum, s);
MagicStrings.Append (' Uhr)', s);
MagicStrings.Insert(cStatusDate, s, 0);
RETURN TRUE;
END; |
|headerKomAnz : IF comment() THEN RETURN TRUE END;
|headerEmptyLine: MagicStrings.Assign(' ', s); RETURN TRUE;
END;
END;
END; (* LOOP *)
ELSE
RETURN FALSE
END;
END grinGetHeaderInfo;
(*--- Infozeilen/Fenstertitel einstellen -----------------------*)
(*$H+*)
PROCEDURE ObjcDraw(win, obj : INTEGER; depth : CARDINAL);
(* Wg MultiTOS: bis auf die Prozedur, die der Editor bekommt *)
(* alles schn ber die Rechteckliste ausgeben *)
(* add: Object, das noch dazwischen liegt *)
(* Taucht in dieser Form nur fr ((Tochter)-Tochter)objekte des Grundobjektes *)
VAR r : GrafBase.Rectangle;
ptr: oneWindowPtr;
BEGIN
IF handlePool.FindEntry(ADR(win), FindWinCond, windows, ptr) THEN
mtUtils.ObjcPos (infoAdr, obj, r.x, r.y);
DEC (r.x); DEC (r.y);
r.w := infoAdr^[obj].obWidth+1;
r.h := infoAdr^[obj].obHeight+1;
ptr^.inObjcDraw := TRUE;
WdwManager.RedrawWdw (win, r);
ptr^.inObjcDraw := FALSE;
END;
END ObjcDraw;
(*$H=*)
PROCEDURE AdjustPosition(x,y,w : INTEGER);
(* Position des Objektes an neue Fensterposition anpassen *)
BEGIN
infoAdr^[0].obX := x; infoAdr^[0].obY := y;
infoAdr^[0].obWidth := w;
(*
(* Ist fehlerhaft: Bei sehr kleinen Fensterbreiten wird eine negative Breite berechnet! *)
infoAdr^[MausTauschrsc.wbanzeige].obWidth := infoAdr^[0].obWidth-infoAdr^[MausTauschrsc.wbanzeige].obX;
*)
END AdjustPosition;
(* TYPE dirType = (dPrevMess, dNextMess, dUpMess, dDownMess, dLeftMess, dRightMess, dReturn, dJump, dGroupJump);*)
PROCEDURE dirPossible(ptr : oneWindowPtr; dir : dirType; withShift: BOOLEAN):BOOLEAN;
(* Kann man sich in die gewnschte Richtung bewegen? *)
VAR fromWhere : CARDINAL;
BEGIN
WITH ptr^ DO
CASE dir OF
dPrevMess : IF UserBLK.AutoUndo THEN
fromWhere := lastPos
ELSE
fromWhere := mess.MailNr
END;
IF withShift THEN (* shift - auf jeden Fall normale Routine verwenden, nicht die Version aus den Listen! *)
(* Achtung! Shift hat jetzt eine Doppelbedeutung: *)
(* Listen - normales vorwrts/rckwrts laufen *)
(* normal - toggelt gelesene ignorieren *)
RETURN grinNextMess(fromWhere, FALSE, FALSE, 0, NIL) # 0FFFFH;
ELSE
RETURN nextMsg (fromWhere, FALSE, FALSE, listHdl, NIL) # 0FFFFH
END;
(* NIL heit hier: Nix "Gelesene ignorieren", 2. FALSE : Einstellung auch bei shift nicht invertieren (wrde aber eh' nicht beachtet) *)
| dNextMess : IF UserBLK.AutoUndo THEN
fromWhere := lastPos
ELSE
fromWhere := mess.MailNr
END;
IF withShift THEN
RETURN grinNextMess(fromWhere, TRUE, FALSE, 0, NIL) < mess.MailAnz;
ELSE
RETURN nextMsg (fromWhere, TRUE, FALSE, listHdl, NIL) < mess.MailAnz
END;
| dUpMess : RETURN (mess.up # dataSys.empty) & (mess.up # dataSys.notSaved)
| dDownMess : RETURN mess.down # dataSys.empty
| dLeftMess : RETURN (mess.left # dataSys.empty)
| dRightMess: RETURN (mess.right # dataSys.empty)
| dReturn : RETURN ptr^.lastPos # mess.MailNr
ELSE
RETURN TRUE;
END;
END;
END dirPossible;
PROCEDURE whiteNr(dir : dirType):INTEGER;
(* liefert Resourceindex des weien Pfeils *)
BEGIN
CASE dir OF
dPrevMess : RETURN MausTauschrsc.wprevmess
| dNextMess : RETURN MausTauschrsc.wnextmess
| dUpMess : RETURN MausTauschrsc.wupmess
| dDownMess : RETURN MausTauschrsc.wdownmess
| dLeftMess : RETURN MausTauschrsc.wleftmess
| dRightMess: RETURN MausTauschrsc.wrightmess
| dReturn : RETURN MausTauschrsc.return
ELSE
END;
END whiteNr;
PROCEDURE blackNr(dir : dirType):INTEGER;
(* liefert Resourceindex des schwarzen Pfeils *)
BEGIN
CASE dir OF
dPrevMess : RETURN MausTauschrsc.wprevmess
| dNextMess : RETURN MausTauschrsc.wnextmess
| dUpMess : RETURN MausTauschrsc.whupmess
| dDownMess : RETURN MausTauschrsc.whdownmess
| dLeftMess : RETURN MausTauschrsc.whleftmess
| dRightMess: RETURN MausTauschrsc.whrightmess
| dReturn : RETURN MausTauschrsc.hreturn
ELSE
END;
END blackNr;
PROCEDURE BlackArrow(win : INTEGER; dir : dirType);
(* Richtungspfeil schwarz einfrben *)
VAR clip : GrafBase.Rectangle;
BEGIN
WdwManager.GetWdwWork (win, clip);
AdjustPosition(clip.x, clip.y, clip.w);
CASE dir OF
dPrevMess,
dNextMess : mtUtils.InclState (infoAdr, blackNr(dir), MagicAES.SELECTED);
ELSE
mtUtils.ExclFlag (infoAdr, blackNr(dir), MagicAES.HIDETREE);
END;
ObjcDraw(win, whiteNr(dir), 2);
END BlackArrow;
PROCEDURE WhiteArrow(win: INTEGER; dir : dirType; redraw: BOOLEAN);
(* Flag wieder zurcknehmen, gezeichnet werden mu noch *)
BEGIN
CASE dir OF
dPrevMess,
dNextMess : mtUtils.ExclState (infoAdr, blackNr(dir), MagicAES.SELECTED);
ELSE
mtUtils.InclFlag (infoAdr, blackNr(dir), MagicAES.HIDETREE);
END;
IF redraw THEN ObjcDraw(win, whiteNr(dir), 2); END;
END WhiteArrow;
PROCEDURE ComposeInfoline(ptr : oneWindowPtr);
VAR tmp : ARRAY [0..10] OF CHAR;
BEGIN
WITH ptr^ DO
MagicStrings.Assign(rawInfoline, info);
VDIStandards.StatusCheck(mess.StatusBits);
IF mess.left # dataSys.empty THEN info[0] := 04C END;
IF mess.up # dataSys.empty THEN info[1] := 01C END;
IF mess.down # dataSys.empty THEN info[2] := 02C END;
IF mess.right # dataSys.empty THEN info[3] := 03C END;
IF 0 IN mess.StatusBits THEN info[5] := 'L' END;
IF 1 IN mess.StatusBits THEN info[6] := 'F' END;
IF 2 IN mess.StatusBits THEN info[7] := 'I' END;
IF 3 IN mess.StatusBits THEN info[8] := 'T' END;
IF 4 IN mess.StatusBits THEN info[9] := 'D' END;
IF 5 IN mess.StatusBits THEN info[10] := 'K' END;
IF 6 IN mess.StatusBits THEN info[11] := 'B' END;
IF 7 IN mess.StatusBits THEN info[12] := '1' END;
IF 8 IN mess.StatusBits THEN info[13] := '2' END;
IF 9 IN mess.StatusBits THEN info[14] := 'V' END;
IF mess.EigeneNachricht & (mess.Gruppe = dataSys.private) THEN
MagicStrings.Append(openBracket, info);
MagicStrings.Append(mess.Datum, info);
MagicStrings.Append(closeBracket, info);
MagicStrings.Append(spaceString, info);
END;
(*
IF mess.MailAnz = 1 THEN
infoAdr^[MausTauschrsc.wanzeige].obWidth := infoAdr^[MausTauschrsc.wbanzeige].obWidth;
ELSE
infoAdr^[MausTauschrsc.wanzeige].obWidth := BinOps.HigherInt(1,
SHORT((LONG(CARDINAL(infoAdr^[MausTauschrsc.wbanzeige].obWidth)) * LONG(mess.MailNr)) DIV LONG(mess.MailAnz-1)));
END;
*)
MagicStrings.Append(mess.Betreff^, info);
(* Statusinformationen reinkopieren, Achtung, wenn sie nicht *)
(* zusammengestellt wurde! *)
MagicStrings.Copy(info, 5, 10, tmp);
mtUtils.SetObjcString (infoAdr, MausTauschrsc.wstati, tmp);
mtUtils.SetState (infoAdr, MausTauschrsc.winfo, MagicAES.SELECTED, ptr^.viewHeader = vhFull);
END;
END ComposeInfoline;
PROCEDURE SetNShowNewStates(ptr : oneWindowPtr);
VAR clip : GrafBase.Rectangle;
BEGIN
ComposeInfoline(ptr);
WdwManager.GetWdwWork (ptr^.win, clip);
AdjustPosition(clip.x, clip.y, clip.w);
ObjcDraw(ptr^.win, MausTauschrsc.wstati, 1);
WITH ptr^ DO
msgList.listChangeFlags (listHdl, win, mess.MailNr, mess.StatusBits);
END;
END SetNShowNewStates;
PROCEDURE setState(ptr : oneWindowPtr);
(* Status bei persnlichen Msgs setzen *)
(* Achtung, kopiert direkt in die Resource, deswegen mu *)
(* dort gengend Platz vorhanden sein! *)
VAR status : ARRAY[0..18] OF CHAR;
(* Wenn grer, dann auch in der Resource anpassen! *)
BEGIN
WITH ptr^ DO
IF mess.Gruppe = dataSys.private
THEN
GetStatusText (mess.Status, status);
mtUtils.SetObjcString (infoAdr, MausTauschrsc.wmperstatus, status);
mtUtils.ExclFlag (infoAdr, MausTauschrsc.wmperstatus, MagicAES.HIDETREE);
ELSE
mtUtils.InclFlag (infoAdr, MausTauschrsc.wmperstatus, MagicAES.HIDETREE);
END;
END;
END setState;
TYPE changeProc = PROCEDURE((* oldBits *) BITSET):BITSET; (* newBits *)
(* Da sie als Prozedurparameter bentigt wird, hier als globale Prozedur mit Variablen *)
VAR CLEARBITS, SETBITS : BITSET;
PROCEDURE newBits(old : BITSET):BITSET;
BEGIN
RETURN (old-CLEARBITS)+SETBITS;
END newBits;
(*$H+*)
PROCEDURE iInternalChange(handle : handlePool.oneHandlePtr; gruppe, MailNr : CARDINAL; actualBits : BITSET; newBits : changeProc);
(* alle Fenster werden durchsucht, ob sie diese Msg *)
(* aus dieser Gruppe darstellen und dort der Status gesetzt *)
(*$Z-*)
PROCEDURE scanWinCond(e, i : ADDRESS):BOOLEAN;
(* Abbruchprozedur, wie in <Lists> gefordert *)
VAR p : oneWindowPtr; old : BITSET;
BEGIN
IF e # NIL THEN
p := e;
IF (p^.mess.Gruppe = gruppe) & (p^.mess.MailNr = MailNr) THEN
WITH p^ DO
old := mess.StatusBits;
mess.StatusBits := newBits(mess.StatusBits);
IF (dataSys.bGelesen IN old) & ~(dataSys.bGelesen IN mess.StatusBits) THEN
(* Der andere Fall ist unkritisch.. :-) *)
p^.readchange := TRUE
END;
END;
SetNShowNewStates(p);
END;
END;
RETURN FALSE
END scanWinCond;
(*$Z=*)
BEGIN
data.SetBits(handle^.Zugriff, MailNr, newBits(actualBits));
(* Jetzt alle Eintrge durchsuchen und die Stati neu setzen *)
Lists.ResetList(windows);
Lists.ScanEntries(windows, Lists.forward, scanWinCond, NIL, v.bool);
END iInternalChange;
PROCEDURE InternalChange(ptr : oneWindowPtr; newBits : changeProc);
BEGIN
WITH ptr^ DO
iInternalChange(handle, mess.Gruppe, mess.MailNr, mess.StatusBits, newBits);
END;
END InternalChange;
(*$H=*)
PROCEDURE iChangeState(handle : handlePool.oneHandlePtr; gruppe, MailNr : CARDINAL; actualBits : BITSET; oldState, newState : CHAR);
(* Alle Fenster werden durchsucht, ob sie dieselbe Msg aus dieser Gruppe darstellen *)
(* und dort auch der Status gesetzt *)
(*$A+,Z-*)
PROCEDURE scanWinCond(e, i : ADDRESS):BOOLEAN;
(* Abbruchprozedur, wie in <Lists> gefordert *)
VAR p : oneWindowPtr;
clip : GrafBase.Rectangle;
BEGIN
IF e # NIL THEN
p := e;
IF (p^.mess.Gruppe = gruppe) & (p^.mess.MailNr = MailNr) THEN
WITH p^ DO
WdwManager.GetWdwWork (win, clip);
AdjustPosition(clip.x, clip.y, clip.w);
mess.Status := newState;
setState(p);
ObjcDraw(win, MausTauschrsc.wmperstatus, 1);
END;
END;
END;
RETURN FALSE
END scanWinCond;
(*$A=,Z=*)
(* Status in Datenbank und interner Struktur ndern sowie zeichnen *)
BEGIN
data.ChangeState(handle^.Zugriff, MailNr, newState);
Lists.ResetList(windows);
Lists.ScanEntries(windows, Lists.forward, scanWinCond, NIL, v.bool);
IF newState = 'Z' THEN
CLEARBITS := {};
SETBITS := {dataSys.bAntworten};
iInternalChange(handle, gruppe, MailNr, actualBits, newBits);
ELSIF (newState = 'B') OR (newState = 'G') THEN
CLEARBITS := {dataSys.bAntworten};
SETBITS := {};
iInternalChange(handle, gruppe, MailNr, actualBits, newBits);
END;
END iChangeState;
PROCEDURE changeState(ptr : oneWindowPtr; newState : CHAR);
(* ptr : Das Fenster, das die nderung hervorgerufen hat *)
(* Anschlieend werden alle anderen Fenster durchsucht, ob sie dieselbe Msg *)
(* aus dieser Gruppe darstellen und dort auch der Status gesetzt *)
(* Status in Datenbank und interner Struktur ndern sowie zeichnen *)
BEGIN
WITH ptr^ DO
iChangeState(handle, mess.Gruppe, mess.MailNr, mess.StatusBits, mess.Status, newState);
END;
END changeState;
PROCEDURE grinResetState(REF id : ARRAY OF CHAR);
(* Den Status einer persnlichen Msg zurcksetzen, wenn eine noch nicht abgeschickte *)
(* Antwort dazu gelscht wird. *)
VAR handle : handlePool.oneHandlePtr;
which : CARDINAL;
own : BOOLEAN;
state : CHAR;
bits : BITSET;
BEGIN
IF handlePool.GetOneDatahandle(dataSys.private, handle) THEN
which := data.NumberOfID(handle^.Zugriff, id);
IF data.error = data.noError THEN
IF ~data.HasAnswer(handle^.Zugriff, which, bits) THEN
data.ReadPersState(handle^.Zugriff, which, state, own, v.bset);
IF state = 'B' THEN iChangeState(handle, dataSys.private, which, bits, 'B', 'Z'); END;
END;
END;
handlePool.FreeOneDataHandle(handle);
END;
END grinResetState;
PROCEDURE MakeInfoline(ptr : oneWindowPtr);
(* Infozeile und die Box bereitstellen *)
VAR scrap : ARRAY[0..4] OF CHAR;
num : ARRAY[0..12] OF CHAR;
dirZaehl : dirType;
BEGIN
WITH ptr^ DO
IF inObjcDraw THEN RETURN END;
ComposeInfoline(ptr);
FOR dirZaehl := dPrevMess TO dReturn DO
WhiteArrow(win, dirZaehl, FALSE);
IF dirPossible(ptr, dirZaehl, TRUE) THEN
mtUtils.ExclState (infoAdr, whiteNr(dirZaehl), MagicAES.DISABLED);
ELSE
mtUtils.InclState (infoAdr, whiteNr(dirZaehl), MagicAES.DISABLED);
END;
END;
mtUtils.SetObjcString (infoAdr, MausTauschrsc.wwegen, ptr^.mess.Betreff^);
IF (ptr^.mess.EigeneNachricht) & (mess.Gruppe = dataSys.private)
THEN
mtUtils.SetObjcString (infoAdr, MausTauschrsc.wvon, ptr^.mess.Empfaenger^);
ELSE
IF ptr^.mess.name^[0] = 0C THEN
mtUtils.SetObjcString (infoAdr, MausTauschrsc.wvon, ptr^.mess.Absender^);
ELSE
mtUtils.SetObjcString (infoAdr, MausTauschrsc.wvon, ptr^.mess.name^);
END;
END;
mtUtils.SetObjcStringAdr (infoAdr, MausTauschrsc.wdatum, ADR(ptr^.mess.Datum));
IF mess.EigeneNachricht & (mess.Gruppe = dataSys.private)
THEN
mtUtils.SetObjcString (infoAdr, MausTauschrsc.wprevon, 'An:');
ELSE
mtUtils.SetObjcString (infoAdr, MausTauschrsc.wprevon, 'Von:');
END;
IF mess.KommentarAnzahl < 100 THEN
MagicConvert.CardToStr(mess.KommentarAnzahl, 2, scrap);
ELSE
scrap := 'xx';
END;
mtUtils.SetObjcString (infoAdr, MausTauschrsc.wkomanz, scrap);
IF mess.up = dataSys.notSaved THEN
mtUtils.ExclFlag (infoAdr, MausTauschrsc.deletedup, MagicAES.HIDETREE);
ELSE
mtUtils.InclFlag (infoAdr, MausTauschrsc.deletedup, MagicAES.HIDETREE);
END;
IF dataSys.bOwnMessage IN mess.StatusBits THEN
mtUtils.SetObjcString(infoAdr, MausTauschrsc.showownmessage, 'E');
mtUtils.ExclFlag (infoAdr, MausTauschrsc.showownmessage, MagicAES.HIDETREE);
ELSIF (dataSys.bComToOwnMessage IN mess.StatusBits) OR
(dataSys.bOldComToOwnMessage IN mess.StatusBits) THEN
mtUtils.SetObjcString(infoAdr, MausTauschrsc.showownmessage, 'K');
mtUtils.ExclFlag (infoAdr, MausTauschrsc.showownmessage, MagicAES.HIDETREE);
ELSE
mtUtils.InclFlag (infoAdr, MausTauschrsc.showownmessage, MagicAES.HIDETREE);
END;
IF mess.distribution # data.dNone THEN
mtUtils.SetObjcString(infoAdr, MausTauschrsc.stdistribution, CHR(ORD(mess.distribution)+ORD('K')));
mtUtils.ExclFlag (infoAdr, MausTauschrsc.stdistribution, MagicAES.HIDETREE);
(*
ELSIF mess.distribution = data.dMausNet THEN
mtUtils.SetObjcString(infoAdr, MausTauschrsc.stdistribution, 'M');
mtUtils.ExclFlag (infoAdr, MausTauschrsc.stdistribution, MagicAES.HIDETREE);
ELSIF mess.distribution = data.dNet THEN
mtUtils.SetObjcString(infoAdr, MausTauschrsc.stdistribution, 'N');
mtUtils.ExclFlag (infoAdr, MausTauschrsc.stdistribution, MagicAES.HIDETREE);
*)
ELSE (* Keine Distribution *)
mtUtils.InclFlag (infoAdr, MausTauschrsc.stdistribution, MagicAES.HIDETREE);
END;
MagicConvert.CardToStr(mess.MailNr+1, 0, num);
MagicStrings.Append('/', num);
MagicConvert.CardToStr(mess.MailAnz, 0, scrap);
MagicStrings.Append(scrap, num);
mtUtils.SetObjcString (infoAdr, MausTauschrsc.wpos, num);
END; (* WITH ptr^ *)
setState(ptr);
END MakeInfoline;
PROCEDURE MakeTitle(ptr : oneWindowPtr);
BEGIN
WITH ptr^ DO
GroupSelect.GroupName(handle^.group, title);
ConfVars.GetConfDefBool (cSetAppName, v.bool, TRUE);
IF CatGlobal.multiTask & v.bool
THEN
MagicStrings.Insert ('[CAT] ', title, 0);
END;
MagicStrings.Insert (' ', title, 0);
MagicStrings.Append (' ', title);
END;
END MakeTitle;
(*--- Umschalten einer Message ---------------------*)
PROCEDURE setReadFlag(ptr : oneWindowPtr);
PROCEDURE new(old : BITSET):BITSET; BEGIN RETURN ptr^.mess.StatusBits; END new;
BEGIN
IF ~(dataSys.bGelesen IN ptr^.mess.StatusBits) & ~ptr^.readchange THEN
INCL(ptr^.mess.StatusBits, dataSys.bGelesen);
data.SetBits(ptr^.handle^.Zugriff, ptr^.mess.MailNr, ptr^.mess.StatusBits);
InternalChange(ptr, new);
END;
END setReadFlag;
PROCEDURE StoreUndoPos(ptr : oneWindowPtr);
(* Speichert die letzten Positionen fr <undo> *)
BEGIN
WITH ptr^ DO
undoPos := mess.MailNr;
undoGroup := mess.Gruppe;
END;
END StoreUndoPos;
PROCEDURE StoreLastPos(ptr : oneWindowPtr; dir : dirType);
(* Speichert die letzte Position fr die Kommentarverkettung *)
BEGIN
WITH ptr^ DO
IF (dir = dPrevMess) OR (dir = dNextMess) OR
(dir = dJump) OR (dir = dGroupJump)
THEN
undoTreeRoot := lastPos;
lastPos := mess.MailNr;
END;
END;
END StoreLastPos;
PROCEDURE SwitchTo(ptr : oneWindowPtr; nr : CARDINAL; dir : dirType; isUndo : BOOLEAN);
(* Wechselt zu der angegebenen Nachricht *)
VAR last : CARDINAL;
inEffMode : BOOLEAN;
num : INTEGER;
iFont,
iFontSize : INTEGER;
varName : CatTypes.String255;
BEGIN
IF (nr # dataSys.empty) & (nr # dataSys.notSaved) &
((nr # ptr^.mess.MailNr) OR (dir=dNextMess) OR (dir = dJump) OR (dir = dNone))
THEN
IF ptr^.treeMode THEN
DEALLOCATE(ptr^.stack, 0);
ptr^.treeMode := FALSE;
END;
IF (dir # dNone) & (dir # dJump) & (dir # dGroupJump) THEN
BlackArrow(ptr^.win, dir);
END;
IF (dir # dGroupJump) & (dir # dNone) THEN
(* Dann ist dieser Handle schon freigegeben und das Flag auch schon gesetzt *)
setReadFlag(ptr);
StoreUndoPos(ptr);
last := ptr^.mess.MailNr;
ELSE
last := dataSys.empty;
END;
ptr^.readchange := FALSE; (* NACH setReadFlag, jetzt neue Msg, User hat noch nix getan *)
DEALLOCATE(ptr^.mess.InfoStrings, 0);
IF GetOneMessage(ptr, nr) THEN
IF isUndo THEN
v.card := ptr^.lastPos;
ptr^.lastPos := ptr^.undoTreeRoot;
ptr^.undoTreeRoot := v.card;
ELSE
StoreLastPos(ptr, dir);
END;
data.SetLastReadMsg(ptr^.handle^.group, ptr^.mess.MailNr);
WITH ptr^ DO (* ... und das ganze an den Editor bergeben *)
inEffMode := CatEdit.GetMode (win, CatEdit.effMode);
CatEdit.ShowNewBuffer (win, title, info, viewBuff (* mess.Text *) ,
viewLen (* LONG(mess.textLen)*) , viewAllocated (* ~refSuppressed *),
isEnriched);
(* dorthin kommt das Fensterhandle im Erfolgsfall *)
(* jetzt im Editor, doppelt wg. Struktur *)
Protokoll.SendNewMsgInWdw();
IF inEffMode # CatEdit.GetMode (win, CatEdit.effMode)
THEN
(* Font umschalten *)
IF CatEdit.GetMode (win, CatEdit.effMode)
OR ~ConfVars.GetConfigInt (cMsgAltFont, iFont)
THEN
(* Mit Effekten, normaler Font *)
num := BinOps.HigherInt (number-1, 0);
Strings.Concat (cMsgFont, StrConv.IntToStr (num, 0), varName, v.bool);
ConfVars.GetConfDefInt (varName, iFont, 1);
Strings.Concat (cMsgSize, StrConv.IntToStr (num, 0), varName, v.bool);
ConfVars.GetConfDefInt (varName, iFontSize, 10);
CatEdit.SelectEditFont (win, iFont, iFontSize);
ELSE
(* Ohne Effekte, Tabellenfont *)
IF ConfVars.GetConfigInt (cMsgAltFont, iFont)
THEN
ConfVars.GetConfDefInt (cMsgAltSize, iFontSize, 10);
CatEdit.SelectEditFont (win, iFont, iFontSize);
END;
END;
END;
IF (dataSys.bComToOwnMessage IN mess.StatusBits) OR
(dataSys.bOldComToOwnMessage IN mess.StatusBits)
(* OR (dataSys.bOwnMessage IN mess.StatusBits)
*)
THEN
IF dir # dNone THEN CatGlobal.Bing (0) END;
END;
(* Das freigeben fehlte noch! *)
IF ptr^.refSuppressed & (ptr^.originalText # NIL)
THEN
DEALLOCATE(ptr^.originalText, 0);
ptr^.refSuppressed := FALSE;
ELSE
IF viewAllocated
THEN
DEALLOCATE(ptr^.mess.Text, 0);
END;
END;
END;
ELSE
(* Hier versuchen, die alte wieder zu ffnen, falls das nicht *)
(* mglich ist, meckern und schlieen *)
v.int := mtAlerts.Alert(1, MTE.msgError);
IF (last # dataSys.empty) & GetOneMessage(ptr, last) THEN
IF ptr^.refSuppressed & (ptr^.originalText # NIL)
THEN
DEALLOCATE(ptr^.originalText, 0);
ptr^.refSuppressed := FALSE;
ELSE
DEALLOCATE(ptr^.mess.Text, 0);
END;
IF ptr^.viewAllocated
THEN
DEALLOCATE(ptr^.viewBuff, 0);
END;
(* Der Editor bekommt von unserer kleinen "Transaktion" nichts mit.. :-) *)
ELSE
(* entweder war dies ein Gruppenwechsel und der Handle ist schon weg *)
(* oder die alte Msg lt sich nicht lesen (Speicher, Platte..) *)
MTE.info (MTE.noOldMsg);
grinClose(ptr^.win);
END;
(* Hier noch die Buttons wieder deselektieren *)
IF (dir # dJump) & (dir # dGroupJump) & (dir # dNone) THEN
WhiteArrow(ptr^.win, dir, TRUE);
END;
END;
END;
END SwitchTo;
PROCEDURE grinSwitchTo (win : INTEGER; which : CARDINAL;
nextMess : grinNextMessProc; listHandle: LONGCARD;
doNotTop: BOOLEAN): BOOLEAN; (* exported *)
(* Schaltet in der aktuellen Gruppe zu der Nachricht which um *)
(* Exportiert fr die Msgliste *)
VAR ptr : oneWindowPtr;
BEGIN
IF handlePool.FindEntry(ADR(win), FindWinCond, windows, ptr)
THEN
msgList.listUnlockWdw (ptr^.listHdl);
ptr^.listHdl := listHandle;
ptr^.nextMsg := nextMess;
SwitchTo (ptr, which, dJump, FALSE);
IF ~doNotTop THEN WdwManager.TopWindow (win); END;
RETURN TRUE;
END;
RETURN FALSE;
END grinSwitchTo;
PROCEDURE grinSetListWdw (win : INTEGER; nextMess : grinNextMessProc;
listHandle: LONGCARD): BOOLEAN; (* exported *)
(* Exportiert fr die Msgliste *)
VAR ptr : oneWindowPtr;
BEGIN
IF handlePool.FindEntry(ADR(win), FindWinCond, windows, ptr)
THEN
ptr^.listHdl := listHandle;
ptr^.nextMsg := nextMess;
RETURN TRUE;
END;
RETURN FALSE;
END grinSetListWdw;
PROCEDURE SwitchToNewGroup(group, nr : CARDINAL; ptr : oneWindowPtr);
(* Hier knnen wir uns notfalls immer noch entscheiden, ein neues Fenster *)
(* aufzumachen. Evtl. auch optional, natrlich! *)
VAR newHandle : handlePool.oneHandlePtr;
BEGIN
setReadFlag(ptr);
IF handlePool.GetOneDatahandle(group, newHandle) THEN
StoreUndoPos(ptr);
handlePool.FreeOneDataHandle(ptr^.handle); (* Alten freigeben *)
ptr^.handle := newHandle;
MakeTitle(ptr);
ptr^.mess.MailNr := 0FFFFH; (* Nunja, wird oben getestet *)
SwitchTo(ptr, nr, dGroupJump, FALSE);
ELSE
(* Das Fenster kann offen bleiben, nichts wurde gendert!
ptr^.handle := NIL;
grinClose(ptr^.win);
*)
MTE.info (MTE.msgError);
END;
END SwitchToNewGroup;
PROCEDURE grinSwitchToMess (win : INTEGER; group : CARDINAL;
whichNumber: getNumberProc):BOOLEAN;
(* Neue Msg in ein Fenster setzen; Fr die Wiedervorlage *)
VAR ptr : oneWindowPtr;
mess: CARDINAL;
newHandle : handlePool.oneHandlePtr;
BEGIN
IF handlePool.FindEntry(ADR(win), FindWinCond, windows, ptr) THEN
msgList.listUnlockWdw (ptr^.listHdl);
ptr^.listHdl := 0;
IF ptr^.mess.Gruppe = group THEN
mess := whichNumber(ptr^.handle^.Zugriff);
SwitchTo (ptr, mess, dJump, FALSE);
ELSE
IF handlePool.GetOneDatahandle(group, newHandle) THEN
mess := whichNumber(newHandle^.Zugriff);
handlePool.FreeOneDataHandle(newHandle); (* Alten freigeben *)
SwitchToNewGroup(group, mess, ptr);
END;
END;
RETURN TRUE;
ELSE
RETURN FALSE;
END;
END grinSwitchToMess;
PROCEDURE grinNextNotWorked (topWin : INTEGER; withShift : BOOLEAN);
(* Springt zur nchsten nicht bearbeiteten Msg bei den persnlichen Msgs *)
VAR ptr : oneWindowPtr;
flagsok : BOOLEAN;
PROCEDURE flagsOk(which : CARDINAL):BOOLEAN;
VAR state : CHAR; own : BOOLEAN; bits : BITSET;
BEGIN
data.ReadPersState(ptr^.handle^.Zugriff, which, state, own, bits);
flagsok := ~own & ((state = 'N') OR (state = 'Z')) OR (bits - (BITSET(0FFFFH)-{dataSys.bAntworten, dataSys.bKommentieren}) # {});
RETURN flagsok;
END flagsOk;
PROCEDURE next(which : CARDINAL):CARDINAL;
BEGIN
(*$R-*)
IF withShift THEN
RETURN which - 1
ELSE
RETURN which + 1
END;
(*$R=*)
END next;
(*$R- wegen Compiler-Bug*)
VAR which : CARDINAL; dreh : CARDINAL;
BEGIN
IF handlePool.FindEntry(ADR(topWin), FindWinCond, windows, ptr) THEN
flagsok := FALSE;
which := ptr^.mess.MailNr;
IF ((which = 0) & withShift) OR ((which >= ptr^.mess.MailAnz) & ~withShift) THEN
ELSE
dreh := 0;
CatGlobal.busyMouse();
REPEAT
which := next(which);
IF ptr^.handle^.group = dataSys.private THEN
INC(dreh);
IF dreh = 10 THEN
dreh := 0; CatGlobal.busyMouse();
IF stopSearch() THEN mtAppl.MouseArrow(); RETURN END;
END;
END;
UNTIL flagsOk(which) OR (which >= ptr^.mess.MailAnz) OR (which = 0) ;
mtAppl.MouseArrow();
END;
IF flagsok THEN
SwitchTo(ptr, which, dJump, FALSE);
ELSE
CatGlobal.Bing (0);
END;
END;
END grinNextNotWorked;
(* TYPE dirType = (dPrevMess, dNextMess, dUpMess, dDownMess, dLeftMess, dRightMess); *)
PROCEDURE grinNextMess (which : CARDINAL; nextJN, withShift : BOOLEAN; listHandle: LONGCARD; winp: ADDRESS): CARDINAL;
(* Default-Prozedur fr nchste/letzte Message *)
(* winp = NIL -> Gelesene ignorieren nicht beachten *)
VAR ptr : oneWindowPtr;
ignoreReadMsgs : BOOLEAN;
PROCEDURE flagsNotOk(which : CARDINAL):BOOLEAN;
VAR flags : BITSET;
BEGIN
data.ReadState(ptr^.handle^.Zugriff, which, flags);
RETURN ((dataSys.bGelesen IN flags) & (ignoreReadMsgs))
OR ((dataSys.bFiltered IN flags) & (UserBLK.ignoreFiltered))
END flagsNotOk;
PROCEDURE next(which : CARDINAL):CARDINAL;
BEGIN
(*$R-*)
IF nextJN THEN
RETURN which + 1
ELSE
RETURN which - 1
END;
(*$R=*)
END next;
(*$R- wegen Compiler-Bug*)
VAR u : BOOLEAN;
BEGIN
which := next(which);
u := UserBLK.ignoreRead;
IF withShift THEN u := ~u END;
ignoreReadMsgs := u;
u := u OR UserBLK.ignoreFiltered;
IF u & (winp # NIL) THEN
ptr := winp;
WHILE (which < ptr^.mess.MailAnz) & (which >= 0) & flagsNotOk(which) DO
which := next(which);
END;
END;
RETURN which
END grinNextMess;
PROCEDURE hasOneInterestingMsg(mode : openMode; gr : CARDINAL; VAR nr : CARDINAL):BOOLEAN;
BEGIN
IF data.LastMsgOfGroup(gr) = dataSys.empty THEN RETURN FALSE END;
(* Leere Gruppen haben keine interessanten Msgs.. *)
CASE mode OF
mFromBeginning : nr := 0; RETURN TRUE
| mFirstNew, mOther : nr := data.FirstNewMsg(gr);
RETURN (nr <= data.LastMsgOfGroup(gr)) &
(nr # dataSys.empty);
| mUnread : nr := data.unreadMsgPos(gr);
RETURN data.unreadMsgCount(gr) # 0;
| mLastPos : nr := data.lastReadMsgOfGroup(gr);
RETURN nr # dataSys.empty;
END;
END hasOneInterestingMsg;
PROCEDURE newGroup(ptr: oneWindowPtr; newWindow: BOOLEAN; withDial: BOOLEAN);
(* Das ist so ein bischen gehackt.. *)
VAR nr : CARDINAL; i : INTEGER; tree : ADDRESS; default : INTEGER;
gz : CARDINAL; (* group-Zhl *)
lHdl: LONGCARD;
BEGIN
CASE ptr^.mode OF
mFromBeginning : default := MausTauschrsc.nextbegin;
| mFirstNew, mOther : default := MausTauschrsc.nextnew;
| mUnread : default := MausTauschrsc.nextunread;
| mLastPos : default := MausTauschrsc.nextlast;
END;
IF ~autoNextGroup
THEN
IF withDial
THEN
tree := MausTauschrsc.TreeAddr^[MausTauschrsc.nextgroup];
(* IF ~mtDials.NewDial(tree) THEN MTE.noMemAlert(); RETURN END; *)
mtUtils.InclFlag(tree, default, MagicAES.DEFAULT);
ptr^.isLocked := TRUE;
i := WinDials.WinDialDo (tree, -1);
ptr^.isLocked := FALSE;
i := INTEGER(BITSET(i) - {15});
mtUtils.ExclState(tree, i, MagicAES.SELECTED);
mtUtils.ExclFlag(tree, default, MagicAES.DEFAULT);
ELSE
i := default;
END;
CASE i OF
MausTauschrsc.nextbegin : ptr^.mode := mFromBeginning;
| MausTauschrsc.nextnew : ptr^.mode := mFirstNew;
| MausTauschrsc.nextunread : ptr^.mode := mUnread;
| MausTauschrsc.nextlast : ptr^.mode := mLastPos;
ELSE
RETURN;
END;
ELSE
IF autoNextPing
THEN
CatGlobal.Bing (1);
END;
END;
(* Zur nchsten Gruppe mit neuen Nachrichten *)
gz := ptr^.handle^.group;
REPEAT
gz := GroupSelect.NextGroupNumber(gz);
UNTIL (gz = 0FFFFH) OR hasOneInterestingMsg(ptr^.mode, gz, nr);
IF (gz # 0FFFFH) & hasOneInterestingMsg(ptr^.mode, gz, nr) THEN
IF newWindow THEN
v.int := grinOpenMessage(gz, nr, grinNextMess, 0, ptr^.mode);
ELSE
(*
msgList.listUnlockWdw (ptr^.listHdl);
ptr^.listHdl := -1;
ptr^.nextMsg := grinNextMess;
*)
IF ~msgList.listChangeGroup (ptr^.listHdl, ptr^.win, nr, gz, ptr^.mode)
THEN
ptr^.listHdl := 0;
ptr^.nextMsg := grinNextMess;
END;
SwitchToNewGroup(gz, nr, ptr);
END;
ELSE
v.int := mtAlerts.Alert (1, MTE.noMsg);
IF v.int = 2
THEN
lHdl := ptr^.listHdl;
WdwManager.SendCloseWindow (ptr^.win);
msgList.listCloseByHandle (lHdl);
END;
END;
END newGroup;
PROCEDURE switch(ptr : oneWindowPtr; direction : dirType; newWindow : BOOLEAN; withShift : BOOLEAN);
VAR toWhere : CARDINAL;
PROCEDURE groupcom();
VAR str : CatTypes.String255; id : CatTypes.Str1023Ptr; len : INTEGER; nr : CARDINAL;
gr : CatTypes.String255; grPtr: CatTypes.Str1023Ptr;
PROCEDURE getIdNumber(ptr : data.OneGroupHandle):CARDINAL;
BEGIN
RETURN data.NumberOfID(ptr, id^);
END getIdNumber;
VAR gNr,
gAnz,
which : CARDINAL;
handle : handlePool.oneHandlePtr;
found : BOOLEAN;
empty : ARRAY[0..1] OF CHAR;
break : BOOLEAN;
BEGIN
empty[0] := 0C;
IF CatEdit.GetTextLine(ptr^.win, 0, str, len) THEN
IF PrepareIDnGroup(str, id, grPtr) THEN
IF GroupSelect.GroupNumber(grPtr^, nr) THEN
v.int := grinOpenWithProc(nr, getIdNumber, grinNextMess, 0, mOther);
RETURN
ELSIF GroupSelect.NetGroupNumber(grPtr^, nr) THEN
v.int := grinOpenWithProc(nr, getIdNumber, grinNextMess, 0, mOther);
RETURN
ELSIF mtAlerts.Alert (1, MTE.noGroup) = 2 THEN
RETURN;
(* So, damit man bei defekter Gruppenangabe noch suchen kann. *)
END;
ELSIF PrepareID(ADR(str), id, v.char, v.card) THEN
IF (mtAlerts.Alert (1, MTE.searchGroupCom) = 2) THEN
RETURN
END;
ELSIF ((ptr^.mess.up = dataSys.notSaved) OR
(ptr^.mess.up = dataSys.empty)) &
(ptr^.mess.KommentierteID[0] = 0C) &
(ptr^.mess.rid^[0] # 0C) & (* data sorgt fr Zuweisung auf emptyString! *)
(ptr^.mess.MailNr > 0) &
data.ComplexSearch(ptr^.handle^.Zugriff,
ptr^.mess.MailNr-1, (* StartNachricht *)
{},
{}, (* Zusammen Suchmaske *)
ptr^.mess.rid^, (* Zu suchender String *)
empty, empty, empty,
SearchHelp.sUEBERALL, SearchHelp.sUEBERALL, SearchHelp.sUEBERALL, SearchHelp.sUEBERALL,
SearchHelp.vUND, SearchHelp.vUND, SearchHelp.vUND,
FALSE, (* gro=klein? *)
{}, {}, (* Zusammen Setzmaske *)
data.SearchSet{data.inText, data.reverse}, (* Was machen? *)
break,
nr)
THEN
v.int := grinOpenMessage(ptr^.handle^.group, nr, grinNextMess, 0, ptr^.mode);
RETURN
ELSE
RETURN
END;
IF ListHelp.SelectGroup (gr, gNr, FALSE, TRUE, TRUE, ListHelp.gsmGroupCom)
THEN
(* Wenn hier jetzt doch eine Gruppenangabe zur Verfgung steht, dann *)
(* mu nur die Gruppe in <gr> gespeichert werden und dann funktioniert *)
(* folgender Aufruf: *)
IF gr[0] # "" THEN
IF handlePool.GetOneDatahandle(gNr, handle) THEN
which := data.NumberOfID(handle^.Zugriff, id^);
IF data.error = data.noError THEN
v.int := grinOpenWithProc(gNr, getIdNumber, grinNextMess, 0, mOther);
found := TRUE;
ELSE
(* Fehlermeldung *)
MTE.info(MTE.noFound);
END;
handlePool.FreeOneDataHandle(handle);
END;
ELSE
gNr := 0;
v.bool := GroupSelect.GroupNumber('$&%$&%$/&/&%&/$&/Ý$/&$/&', gAnz);
(* Wenn es eine Gruppe mit diesem Namen gibt, sprechen wir uns wieder :-) *)
(* Geht auch besser, aber das war hier der einfachste Hack.. *)
found := FALSE;
WHILE (gNr < gAnz) & ~found & ~stopSearch() DO
IF handlePool.GetOneDatahandle(gNr, handle) THEN
which := data.NumberOfID(handle^.Zugriff, id^);
IF data.error = data.noError THEN
v.int := grinOpenWithProc(gNr, getIdNumber, grinNextMess, 0, mOther);
found := TRUE;
END;
handlePool.FreeOneDataHandle(handle);
END;
INC(gNr);
CatGlobal.busyMouse();
END;
mtAppl.MouseArrow();
END;
IF ~found THEN
CatGlobal.Bing (7); (* Bing *)
END;
END;
END;
END groupcom;
BEGIN
IF dirPossible(ptr, direction, withShift) THEN
IF UserBLK.AutoUndo THEN
toWhere := ptr^.lastPos;
setReadFlag(ptr);
ELSE
toWhere := ptr^.mess.MailNr;
END;
CASE direction OF
dPrevMess : IF ~withShift THEN
toWhere := ptr^.nextMsg (toWhere, FALSE, withShift, ptr^.listHdl, ptr);
ELSE
(* Unterscheiden, ob die externe Routine aufgerufen wird -> Listfenster *)
(* dann soll mit shift die normale Routine, ohne Gelesene ignorieren *)
(* aufgerufen werden *)
IF ptr^.nextMsg = grinNextMess THEN
toWhere := grinNextMess (toWhere, FALSE, withShift, 0, ptr);
ELSE
toWhere := grinNextMess (toWhere, FALSE, withShift, 0, NIL);
END;
END;
| dNextMess : IF ~withShift THEN
toWhere := ptr^.nextMsg (toWhere, TRUE, withShift, ptr^.listHdl, ptr)
ELSE
(* Unterscheiden, ob die externe Routine aufgerufen wird -> Listfenster *)
(* dann soll mit shift die normale Routine, ohne Gelesene ignorieren *)
(* aufgerufen werden *)
IF ptr^.nextMsg = grinNextMess THEN
toWhere := grinNextMess (toWhere, TRUE, withShift, 0, ptr);
ELSE
toWhere := grinNextMess (toWhere, TRUE, withShift, 0, NIL);
END;
END;
| dUpMess : toWhere := ptr^.mess.up;
| dDownMess : toWhere := ptr^.mess.down;
| dLeftMess : toWhere := ptr^.mess.left;
| dRightMess : toWhere := ptr^.mess.right;
END;
IF (toWhere = 0FFFFH) OR (toWhere >= ptr^.mess.MailAnz) THEN
IF direction = dNextMess THEN newGroup(ptr, newWindow, TRUE) END;
ELSE
IF newWindow THEN
v.int := grinOpenMessage(ptr^.handle^.group, toWhere, grinNextMess, 0, ptr^.mode);
ELSE
SwitchTo(ptr, toWhere, direction, FALSE);
END;
END;
ELSIF direction = dNextMess THEN
newGroup(ptr, newWindow, TRUE);
ELSIF direction = dUpMess THEN
(* Hier fr gruppenbergreifende Kommentarverkettung. *)
(* .. und fr die Suche nach Usenet-Verkettung. *)
groupcom();
END;
END switch;
PROCEDURE hiddenFeature(wdw: INTEGER; feature: INTEGER);
(* Setzt alle nachfolgenden Nachrichten in der Gruppe auf Gelesen und
* geht mit dem aktuellen Lesemodus ohne Nachfrage zur nchsten Gruppe
* Modus 1: Alle Nachrichten auf Gelesen setzen, nchste Gruppe
* Modus 2: Einfach zur nchsten Gruppe
*)
VAR ptr : oneWindowPtr;
start: CARDINAL;
i : CARDINAL;
flags : BITSET;
PROCEDURE new(old : BITSET):BITSET; BEGIN RETURN ptr^.mess.StatusBits; END new;
BEGIN
IF (feature # 0) & (feature # 1) & (feature # 2)THEN RETURN END;
(* Erstmal alles auf Gelesen setzen *)
IF handlePool.FindEntry(ADR(wdw), FindWinCond, windows, ptr) THEN
(* Fenster ist da, alle auf Gelesen setzen *)
INCL(ptr^.mess.StatusBits, dataSys.bGelesen);
data.SetBits(ptr^.handle^.Zugriff, ptr^.mess.MailNr, ptr^.mess.StatusBits);
InternalChange(ptr, new);
IF feature = 0
THEN
start := ptr^.mess.MailNr
ELSIF feature = 1
THEN
start := 0;
END;
IF feature < 2 THEN
FOR i := start TO ptr^.mess.MailAnz-1 DO
data.ReadState (ptr^.handle^.Zugriff, i, flags);
IF ~(dataSys.bGelesen IN flags)
THEN
INCL (flags, dataSys.bGelesen);
data.SetBits (ptr^.handle^.Zugriff, i, flags);
END;
END;
END;
(* So, und jetzt zur nchsten Gruppe *)
newGroup (ptr, FALSE, FALSE);
END;
END hiddenFeature;
(*-- Clicks in den Statusbereich/ Status invertieren --------------*)
PROCEDURE InternalInvert(ptr : oneWindowPtr; whichState : CARDINAL);
(* ptr : Das Fenster, das die nderung hervorgerufen hat *)
(* Anschlieend werden alle anderen Fenster durchsucht, ob sie dieselbe Msg *)
(* aus dieser Gruppe darstellen und dort auch der Status gesetzt *)
VAR newFlags : BITSET;
PROCEDURE new(old : BITSET):BITSET;
BEGIN
RETURN newFlags;
END new;
BEGIN
WITH ptr^ DO
(* neue Flags berechnen *)
newFlags := mess.StatusBits;
IF whichState IN newFlags THEN
EXCL(newFlags, whichState);
ELSE
INCL(newFlags, whichState);
END;
InternalChange(ptr, new);
END;
END InternalInvert;
PROCEDURE ClickInvert(ptr : oneWindowPtr; mx, my : INTEGER);
VAR pixelPerState : INTEGER; state : CARDINAL;
BEGIN
DEC(mx, infoAdr^[MausTauschrsc.wstati].obX);
DEC(mx, infoAdr^[0].obX);
pixelPerState := infoAdr^[MausTauschrsc.wstati].obWidth DIV StateAnz;
state := CARDINAL(mx DIV pixelPerState);
InternalInvert(ptr, state);
END ClickInvert;
(*--- eigene Infozeile verwalten --------------*)
PROCEDURE InitPopup();
VAR str : ARRAY [0..40] OF CHAR;
BEGIN
mtUtils.ObjcString (flagPop, MausTauschrsc.popuflg1, str);
CatGlobal.MakeStr (UserBLK.ustr1, str);
mtUtils.SetObjcString (flagPop, MausTauschrsc.popuflg1, str);
mtUtils.ObjcString (flagPop, MausTauschrsc.popuflg2, str);
CatGlobal.MakeStr (UserBLK.ustr2, str);
mtUtils.SetObjcString (flagPop, MausTauschrsc.popuflg2, str);
END InitPopup;
PROCEDURE InitRsc();
BEGIN
infoAdr := MausTauschrsc.TreeAddr^[MausTauschrsc.grsteuer];
addInfo := MausTauschrsc.TreeAddr^[MausTauschrsc.addinfo];
flagPop := MausTauschrsc.TreeAddr^[MausTauschrsc.flagpop];
END InitRsc;
PROCEDURE grinKey(win : INTEGER; VAR scan, c : CHAR;
VAR kstate : BITSET; VAR moreChars : BOOLEAN):BOOLEAN;FORWARD;
PROCEDURE CheckPersonal (ptr : oneWindowPtr; VAR c : CHAR; kstate: BITSET;
VAR done: BOOLEAN):BOOLEAN;
(* gibt an, ob der Buchstabe nicht ok ist *)
(* done gibt an, ob der Tastendruck behandelt wurde *)
BEGIN
done := FALSE;
IF CatGlobal.WithCtrl (kstate) OR CatGlobal.WithAlt (kstate) THEN RETURN FALSE END;
IF (ptr^.handle^.group = dataSys.private) &
(~ptr^.mess.EigeneNachricht) THEN
IF (ptr^.mess.Status = 'N')
THEN
(* Nur in diesem Fall kann eine Eingabe nicht Ok sein! *)
(* Nicht gelesene und Zurckgestellte behandeln, *)
(* letztere nur wenn nicht nochmal zurckgestellt *)
IF (c = 'N') OR (c = 'Z') THEN
IF c = 'N' THEN
SendState(ptr^.mess.MailID^, 'G');
changeState(ptr, 'G');
done := TRUE;
ELSIF c = 'Z' THEN
SendState(ptr^.mess.MailID^, 'Z');
changeState(ptr, c);
done := TRUE;
c := 'N';
END;
RETURN FALSE;
ELSE
RETURN TRUE
END
ELSIF (ptr^.mess.Status = 'Z') & (c = 'N') THEN
SendState(ptr^.mess.MailID^, 'G');
changeState(ptr, 'G');
done := TRUE;
ELSIF (ptr^.mess.Status = 'G') & (c = 'Z') THEN
SendState(ptr^.mess.MailID^, 'Z');
changeState(ptr, 'Z');
c := 'N';
done := TRUE;
END;
END;
RETURN FALSE;
END CheckPersonal;
(* Bewegung zur nchsten/vorherigen in der privaten Gruppe
*)
PROCEDURE NextPrevPrivate (ptr: oneWindowPtr; scan, char : CHAR;
kstate: BITSET): BOOLEAN;
VAR
chkPers : BOOLEAN;
bDone : BOOLEAN;
BEGIN
chkPers := CheckPersonal (ptr, char, kstate, bDone);
IF chkPers & restrictedMoves
THEN
CASE mtAlerts.Alert (1, "[1][CAT:|Neue persnliche Nachricht:|(B)eantworten|(Z)urckstellen|(N)icht antworten][[Beantworten|[Zurckstellen|[Nicht antworten]") OF
1 : char := 'B'; |
2 : char := 'Z'; |
3 : char := 'N'; |
ELSE
END;
scan := 0C;
kstate := {};
RETURN grinKey (ptr^.win, scan, char, kstate, bDone);
END;
RETURN FALSE;
END NextPrevPrivate;
PROCEDURE WriteToClip (REF str : ARRAY OF CHAR);
CONST scrapName = 'SCRAP.TXT';
VAR name : ARRAY [0..255] OF CHAR;
hdl : INTEGER;
cnt : LONGCARD;
BEGIN
IF ~Clip.GetScrap (name) THEN RETURN END;
MagicStrings.Append (scrapName, name);
hdl := MagicDOS.Fcreate (name, {});
IF hdl < 0 THEN RETURN END;
cnt := LENGTH (str);
MagicDOS.Fwrite (hdl, cnt, CADR(str));
hdl := MagicDOS.Fclose (hdl);
Clip.ScrapWritten({MagicAES.SCFTEXT}, ".TXT");
IF ~Clip.GetScrap (name) THEN RETURN END;
Protokoll.SendPathUpdate (name);
END WriteToClip;
TYPE ddExt = ARRAY [0..3] OF CHAR;
CONST grinExt = ".FLT";
grinDDName = "CAT Filterinformation";
PROCEDURE grinDDGetMaxExts (wdw: INTEGER): INTEGER;
VAR ptr : oneWindowPtr;
BEGIN
IF handlePool.FindEntry(ADR(wdw), FindWinCond, windows, ptr) THEN
RETURN 1;
END;
RETURN 0;
END grinDDGetMaxExts;
PROCEDURE grinDDGetExt (wdw: INTEGER; mode: INTEGER; VAR ext: ARRAY OF CHAR): BOOLEAN;
VAR ptr : oneWindowPtr;
BEGIN
IF handlePool.FindEntry(ADR(wdw), FindWinCond, windows, ptr) THEN
IF mode = WdwManager.HDRFIRST
THEN
MagicStrings.Assign (grinExt, ext);
RETURN TRUE;
END;
END;
RETURN FALSE;
END grinDDGetExt;
PROCEDURE grinDDGetExtName (wdw: INTEGER; idx: INTEGER; VAR name: ARRAY OF CHAR);
VAR ptr : oneWindowPtr;
BEGIN
MagicStrings.Assign ("", name);
IF handlePool.FindEntry(ADR(wdw), FindWinCond, windows, ptr) THEN
IF idx = 0
THEN
MagicStrings.Assign (grinDDName, name);
END;
END;
END grinDDGetExtName;
PROCEDURE grinDDGetSize (wdw: INTEGER; idx: INTEGER; VAR size: LONGCARD);
VAR ptr : oneWindowPtr;
BEGIN
size := 0;
IF handlePool.FindEntry(ADR(wdw), FindWinCond, windows, ptr) THEN
(* Wir bergeben folgendes:
* From: Absender, 256 Zeichen
* TAB
* Topic: Betreff, 256 Zeichen
* TAB
* Group: Gruppe, 256 Zeichen
* TAB
*)
size := LENGTH (cFrom) + LENGTH (cSubject) + LENGTH (cGroup) + 771 (* 256*3 + 3 *);
END;
END grinDDGetSize;
PROCEDURE grinDDGetData (wdw: INTEGER; idx: INTEGER; VAR data: ADDRESS);
VAR ptr : oneWindowPtr;
size : LONGCARD;
pos : LONGCARD;
text : CatTypes.LargeTextPtr;
k : LONGCARD;
gName: CatTypes.String255;
BEGIN
data := NIL;
IF handlePool.FindEntry(ADR(wdw), FindWinCond, windows, ptr) THEN
WITH ptr^ DO
grinDDGetSize (wdw, idx, size);
IF (size > 0)
THEN
ALLOCATE (data, size);
IF data = NIL
THEN
RETURN
END;
text := data;
(* Jetzt daten Kopieren *)
pos := 0;
Block.Copy (CADR(cFrom), LENGTH (cFrom), data+ADDRESS(pos));
INC (pos, LENGTH (cFrom));
(* Feld kopieren *)
FOR k := 0 TO 255 DO
text^[pos+k] := ' ';
END;
(* Absender kopieren *)
IF (mess.Absender # NIL) & (ddObjc = MausTauschrsc.wvon)
THEN
Block.Copy (mess.Absender, LENGTH (mess.Absender^), data+ADDRESS(pos));
END;
INC (pos, 256);
Block.Copy (CADR(cTAB), 1, data+ADDRESS(pos));
INC (pos);
Block.Copy (CADR(cSubject), LENGTH (cSubject), data+ADDRESS(pos));
INC (pos, LENGTH (cSubject));
(* zweites Feld kopieren *)
FOR k := 0 TO 255 DO
text^[pos+k] := ' ';
END;
IF (mess.Betreff # NIL) & (ddObjc = MausTauschrsc.wwegen)
THEN
Block.Copy (mess.Betreff, LENGTH (mess.Betreff^), data+ADDRESS(pos));
END;
INC (pos, 256);
Block.Copy (CADR(cTAB), 1, data+ADDRESS(pos));
INC (pos);
(* Jetzt noch Gruppe anhngen *)
Block.Copy (CADR(cGroup), LENGTH (cGroup), data+ADDRESS(pos));
INC (pos, LENGTH (cGroup));
(* Feld kopieren *)
FOR k := 0 TO 255 DO
text^[pos+k] := ' ';
END;
(* Gruppennamen kopieren *)
GroupSelect.GroupName (mess.Gruppe, gName);
Block.Copy (ADR(gName), LENGTH (gName), data+ADDRESS(pos));
INC (pos, 256);
Block.Copy (CADR(cTAB), 1, data+ADDRESS(pos));
END;
END;
END;
END grinDDGetData;
(* Prozeduren, die an CatEdit bergeben werden *)
PROCEDURE click(win, vdiHdl, mx, my : INTEGER;
kstate : BITSET; work : GrafBase.Rectangle);
(* Wird bei Klick in das entsprechende Fenster aufgerufen *)
VAR obj : INTEGER;
ptr : oneWindowPtr;
nw : BOOLEAN; (* "NewWindow" *)
withShift : BOOLEAN;
x, y, i : INTEGER;
res : INTEGER;
s, c : CHAR;
b : BITSET;
more : BOOLEAN;
popStr : CatTypes.String255;
chkPers : BOOLEAN;
newCh : CHAR;
buts : BITSET;
str : CatTypes.String255;
oldX,
oldY : INTEGER;
hdl : INTEGER;
xDiff,
yDiff : INTEGER;
(* Drag&Drop *)
size : LONGCARD;
data : ADDRESS;
siz : CARDINAL;
apId : INTEGER;
BEGIN
IF handlePool.FindEntry(ADR(win), FindWinCond, windows, ptr) THEN
IF ptr^.inEvent THEN RETURN END;
ptr^.inEvent := TRUE;
AdjustPosition(work.x, work.y, work.w);
obj := MagicAES.ObjcFind(infoAdr, 0, MAX(INTEGER), mx, my);
nw := MagicAES.KCTRL IN kstate;
withShift := (MagicAES.KLSHIFT IN kstate) OR (MagicAES.KRSHIFT IN kstate);
newCh := "";
(*
IF (obj # MausTauschrsc.wvon)
& (obj # MausTauschrsc.wwegen)
THEN
mtUtils.Bounce();
END;
*)
(* chkPers := CheckPersonal (ptr, newCh, kstate, v.bool); *)
IF obj = MausTauschrsc.wprevmess THEN
(* Prfen, ob Restricted Mode *)
IF NextPrevPrivate (ptr, 0C, 'L', {})
THEN
ptr^.inEvent := FALSE;
RETURN
END;
IF withShift THEN
IF nw THEN
v.int := grinOpenMessage(ptr^.handle^.group, 0, grinNextMess, 0, ptr^.mode);
ELSE
SwitchTo (ptr, 0, dJump, FALSE)
END;
ELSE
switch(ptr, dPrevMess, nw, withShift)
END;
ELSIF obj = MausTauschrsc.wnextmess THEN
IF NextPrevPrivate (ptr, spaceScan, 0C, {})
THEN
ptr^.inEvent := FALSE;
RETURN
END;
IF withShift THEN
IF nw THEN
v.int := grinOpenMessage(ptr^.handle^.group, 0, grinNextMess, 0, ptr^.mode);
ELSE
SwitchTo (ptr, ptr^.mess.MailAnz-1, dJump, FALSE)
END;
ELSE
switch(ptr, dNextMess, nw, withShift)
END;
ELSIF obj = MausTauschrsc.wupmess THEN switch(ptr, dUpMess, nw, withShift)
ELSIF obj = MausTauschrsc.wdownmess THEN switch(ptr, dDownMess, nw, withShift)
ELSIF obj = MausTauschrsc.wleftmess THEN switch(ptr, dLeftMess, nw, withShift)
ELSIF obj = MausTauschrsc.wrightmess THEN switch(ptr, dRightMess,nw, withShift)
ELSIF obj = MausTauschrsc.wstati THEN ClickInvert(ptr, mx, my);
ELSIF obj = MausTauschrsc.waction THEN
mtUtils.ObjcPos (infoAdr, obj, x, y);
IF ptr^.handle^.group = dataSys.private
THEN
popStr := " Beantworten 'B'| Kopieren 'C'| Gruppenkommentar 'G'| Lschen 'X'| Weitergeben 'W'| Nicht beantworten 'N'| Zurckstellen 'Z'| Wiedervorlegen 'R'";
res := mtPopups.PosPopup(x, y, popStr, '');
CASE res OF
-1 : ptr^.inEvent := FALSE;
RETURN;
| 0 : c := 'b';
| 1 : c := 'c';
| 2 : c := 'g';
| 3 : c := 'x';
| 4 : c := 'w';
| 5 : c := 'n';
| 6 : c := 'z';
| 7 : c := 'r';
ELSE
ptr^.inEvent := FALSE;
RETURN
END;
ELSE
popStr := " Beantworten 'B'| Kommentieren 'K'| Gruppenkommentar 'G'| Lschen 'X'| Wiedervorlegen 'R'";
res := mtPopups.PosPopup(x, y, popStr, '');
CASE res OF
-1 : ptr^.inEvent := FALSE;
RETURN;
| 0 : c := 'b';
| 1 : c := 'k';
| 2 : c := 'g';
| 3 : c := 'x';
| 4 : c := 'r';
ELSE
ptr^.inEvent := FALSE;
RETURN
END;
END;
s := 0C; b := {}; more := FALSE;
v.bool := grinKey (win, s, c, b, more);
ELSIF obj = MausTauschrsc.winfo THEN
c := 'I'; s := 0C; b := {}; more := FALSE;
v.bool := grinKey (win, s, c, b, more);
ELSIF obj = MausTauschrsc.wtree THEN
mtUtils.InclState (infoAdr, obj, MagicAES.SELECTED);
ObjcDraw (ptr^.win, obj, 1);
treeList.treeOpen (ptr^.mess.Gruppe, ptr^.mess.MailNr, ptr^.win);
mtUtils.ExclState (infoAdr, obj, MagicAES.SELECTED);
ObjcDraw (ptr^.win, obj, 1);
ELSIF obj = MausTauschrsc.wpict THEN
mtUtils.InclState (infoAdr, obj, MagicAES.SELECTED);
ObjcDraw (ptr^.win, obj, 1);
ActualName (ptr^.win, popStr);
IF CatGlobal.WithShift (kstate)
THEN
WriteToClip (popStr);
ELSE
Protokoll.SendHelp (popStr);
END;
mtUtils.ExclState (infoAdr, obj, MagicAES.SELECTED);
ObjcDraw (ptr^.win, obj, 1);
ELSIF obj = MausTauschrsc.wlist THEN
mtUtils.InclState (infoAdr, obj, MagicAES.SELECTED);
ObjcDraw (ptr^.win, obj, 1);
s := escScan; b := kstate; c := 0C; more := FALSE;
v.bool := grinKey(win, s, c, b, more);
mtUtils.ExclState (infoAdr, obj, MagicAES.SELECTED);
ObjcDraw (ptr^.win, obj, 1);
ELSIF obj = MausTauschrsc.return THEN SwitchTo(ptr, ptr^.lastPos, dReturn, FALSE);
ELSIF obj = MausTauschrsc.wpop THEN
mtUtils.ObjcPos (infoAdr, obj, x, y);
FOR i := dataSys.bGelesen TO dataSys.bVererben DO
mtUtils.SetState (flagPop, i+1, MagicAES.CHECKED, i IN ptr^.mess.StatusBits);
END;
InitPopup();
res := mtPopups.TreePopup (flagPop, x, y, 0) ;
IF res > 0 THEN
InternalInvert(ptr, res-1);
END;
ELSIF (obj = MausTauschrsc.wvon)
OR (obj = MausTauschrsc.wwegen)
THEN
(* Drag&Drop von Name oder Betreff *)
mtUtils.InclState (infoAdr, obj, MagicAES.SELECTED);
ObjcDraw (ptr^.win, obj, 1);
(* String holen *)
mtUtils.ObjcString (infoAdr, obj, str);
IF LENGTH (str) > 30
THEN
str[28] := '.';
str[29] := '.';
str[30] := '.';
str[31] := 0C;
END;
(* Begin Drag&Drop *)
hdl := mtAppl.VDIHandle;
oldX := mx;
oldY := my;
mtUtils.ObjcArea (infoAdr, obj, v.r);
xDiff := mx - v.r[0];
yDiff := my - v.r[1] - mtAppl.CharHeight;
MagicAES.WindUpdate (MagicAES.BEGMCTRL);
mtAppl.StoreMouse();
mtAppl.MouseHand();
v.int := MagicVDI.SetWritemode (hdl, MagicVDI.XOR);
mtAppl.MouseOff();
MagicVDI.SetTextalignment (hdl, 0, 3, v.int, v.int);
v.int := MagicVDI.SetCharpoints (hdl, 10, v.int, v.int, v.int, v.int);
VDIStandards.Text (FALSE, hdl, mx - xDiff, my - yDiff, str);
mtAppl.MouseOn();
REPEAT
MagicAES.GrafMkstate (mx, my, buts, kstate);
IF (mx # oldX) OR (my # oldY)
THEN
mtAppl.MouseOff();
VDIStandards.Text (FALSE, hdl, oldX - xDiff, oldY - yDiff, str);
VDIStandards.Text (FALSE, hdl, mx - xDiff, my - yDiff, str);
oldX := mx;
oldY := my;
mtAppl.MouseOn();
END;
UNTIL ~(0 IN buts);
(* Text wegzeichnen *)
mtAppl.MouseOff();
VDIStandards.Text (FALSE, hdl, oldX - xDiff, oldY - yDiff, str);
mtAppl.MouseOn();
v.int := MagicVDI.SetWritemode (hdl, MagicVDI.REPLACE);
mtAppl.RestoreMouse();
MagicAES.WindUpdate (MagicAES.ENDMCTRL);
(* Window suchen *)
hdl := MagicAES.WindFind (mx, my);
IF hdl # win
THEN
(* Check if block is marked in editor *)
IF CatEdit.BlockIsMarked (win)
THEN
(* Wir mssen den Block lschen, denn sonst ginge das D&D
* ber den Block
*)
CatEdit.ClearBlock (win);
END;
ptr^.ddObjc := obj;
MagicAES.WindUpdate (MagicAES.ENDUPDATE);
IF ~WdwManager.WdwDDServe (win, mx, my, kstate)
THEN
(* Das ganze per Message verschicken *)
IF WdwManager.GetApId (hdl, apId)
THEN
grinDDGetSize (win, 0, size);
grinDDGetData (win, 0, data);
siz := SHORT (size);
v.bool := Protokoll.Send2Filter (apId, siz, data);
END;
END;
MagicAES.WindUpdate (MagicAES.BEGUPDATE);
END;
(* Ende Drag&Drop *)
mtUtils.ExclState (infoAdr, obj, MagicAES.SELECTED);
ObjcDraw (ptr^.win, obj, 1);
END;
ptr^.inEvent := FALSE;
END;
END click;
PROCEDURE grinTop (win : INTEGER);
VAR ptr : oneWindowPtr;
BEGIN
IF handlePool.FindEntry(ADR(win), FindWinCond, windows, ptr) THEN
VDIStandards.StatusEnable (TRUE);
VDIStandards.StatusCheck(ptr^.mess.StatusBits);
Protokoll.SendNewMsgInWdw();
END;
END grinTop;
PROCEDURE grinUntop (win : INTEGER);
BEGIN
VDIStandards.StatusEnable(FALSE);
END grinUntop;
PROCEDURE getRect(win : INTEGER;
editWork : GrafBase.Rectangle;
VAR userRect,
editWorkRect : GrafBase.Rectangle);
(* Wird aufgerufen, um die Ausmae des am oberen Fensterrandes liegenden Objektes festzustellen *)
VAR ptr : oneWindowPtr;
treeRect : GrafBase.Rectangle;
varName : ARRAY [0..255] OF CHAR;
full : GrafBase.Rectangle;
number : INTEGER;
BEGIN
editWorkRect := editWork;
mtUtils.CalcArea (infoAdr, 0, treeRect);
userRect := GrafBase.Rect(editWork.x, editWork.y, editWork.w, treeRect.h-1 );
INC(editWorkRect.y, userRect.h);
DEC(editWorkRect.h, userRect.h);
(* Aufpassen, falls es zu klein wird *)
IF (win >= 0) & handlePool.FindEntry(ADR(win), FindWinCond, windows, ptr) THEN
number := ptr^.number;
Strings.Concat (cMsgWindow, StrConv.IntToStr (number, 0), varName, v.bool);
WdwManager.GetWdwSize (win, full); (* Gre des Fensters abfragen *)
v.bool := ConfVars.SetConfigRect (varName, full);
END;
END getRect;
PROCEDURE draw(win, vdiHdl : INTEGER; wdwWork, clip : GrafBase.Rectangle;
textCol, backCol : INTEGER);
(* Wird aufgerufen, um den Objektbereich neuzuzeichnen *)
VAR ptr : oneWindowPtr;
BEGIN
IF handlePool.FindEntry(ADR(win), FindWinCond, windows, ptr) THEN
WITH wdwWork DO
AdjustPosition(x, y, w);
END;
MakeInfoline(ptr); (* eben.. *)
VDIUtil.SetTreeColor (infoAdr, textCol, backCol);
MagicAES.ObjcDraw(infoAdr, 0, 8, clip);
END
END draw;
(*--- Allg. Verwaltung ----------------------*)
PROCEDURE grinInit():BOOLEAN;
(* Einiges Initialisieren, gemeckert wird selbst *)
VAR err : BOOLEAN;
BEGIN
IF ~handlePool.InitPool() THEN
MTE.noMemAlert();
RETURN FALSE
END;
InitRsc();
ConfVars.GetConfDefBool(cSuppressRef, RefIdUnterdruecken, FALSE);
ConfVars.GetConfDefBool (cPersRestricted, restrictedMoves, TRUE);
ConfVars.GetConfDefBool (cSpacePaging, spacePaging, FALSE);
ConfVars.GetConfDefBool (cAutoNextGroup, autoNextGroup, FALSE);
ConfVars.GetConfDefBool (cAutoNextPing, autoNextPing, FALSE);
RETURN TRUE
END grinInit;
(* --- Neuzeichnen beim Baum-durchlaufen --- *)
PROCEDURE flagupdate(nr : CARDINAL; newflags : BITSET);
(* Wird an data bergeben, um die genderten Flags beim Baum-durchlaufen neu zu zeichnen *)
(*$Z-*)
PROCEDURE scanWinCond(e, i : ADDRESS):BOOLEAN;
(* Abbruchprozedur, wie in <Lists> gefordert *)
VAR p : oneWindowPtr; clip : ARRAY[0..3] OF INTEGER;
BEGIN
IF e # NIL THEN
p := e;
IF p^.mess.MailNr = nr THEN
p^.mess.StatusBits := newflags;
SetNShowNewStates(p);
END;
END;
RETURN FALSE
END scanWinCond;
(*$Z=*)
BEGIN
Lists.ResetList(windows);
Lists.ScanEntries(windows, Lists.forward, scanWinCond, NIL, v.bool);
END flagupdate;
(* --- nderungen der Flags beim Durchlaufen eines Baumes --- *)
PROCEDURE flagdelete(old : BITSET):BITSET;
(* Gelscht-Flag setzen *)
BEGIN
RETURN old + {dataSys.bTotalloeschung};
END flagdelete;
PROCEDURE flagundelete(old : BITSET):BITSET;
(* Gelscht-Flag lschen *)
BEGIN
RETURN old - {dataSys.bTotalloeschung};
END flagundelete;
(*--- Keyboard-Events --- *)
PROCEDURE grinKey(win : INTEGER; VAR scan, c : CHAR;
VAR kstate : BITSET; VAR moreChars : BOOLEAN):BOOLEAN;
(* Keyboard-Events behandeln, wird vom Editor aufgerufen *)
VAR ptr : oneWindowPtr;
newWindow : BOOLEAN; (* "NewWindow" *)
withAlt : BOOLEAN;
withShift : BOOLEAN;
newCh : CHAR;
res : INTEGER;
gName : CatTypes.String255;
tmpName : CatTypes.String255;
pageW,
pageH : LONGINT;
doc : GrafBase.LongRect;
done : BOOLEAN;
doInvert : BOOLEAN;
flag : INTEGER;
dir : dirType;
needRedraw: BOOLEAN;
varName : CatTypes.String255;
num : INTEGER; (* Fensternummer *)
iFont,
iFontSize : INTEGER;
tmpChar : CHAR;
BEGIN
(* Neue Routine, vernnftig sortiert nach Funktionsgruppen
*)
moreChars := FALSE;
IF handlePool.FindEntry(ADR(win), FindWinCond, windows, ptr) THEN
IF (CatGlobal.WithCtrl (kstate)) OR
(CatGlobal.WithAlt (kstate) & (c = 0C))
THEN
(* Jetzt Tastencodes richtig holen, das AES erzhlt da nur Mll *)
newCh := mtUtils.CharCode (INTEGER(ORD(scan)), kstate);
ELSE
newCh := c;
END;
newCh := CAP(newCh);
(* Sondertasten abfragen *)
newWindow := CatGlobal.WithCtrl (kstate);
withAlt := CatGlobal.WithAlt (kstate);
withShift := CatGlobal.WithShift (kstate);
(* Abfrage ber Scancode *)
WITH ptr^ DO
IF withAlt
THEN
doInvert := TRUE;
CASE newCh OF
'L' : flag := dataSys.bGelesen; |
'F' : flag := dataSys.bFiltered; |
'I' : flag := dataSys.bInteressant; |
'T' : flag := dataSys.bTeilloeschung; |
'D' : flag := dataSys.bTotalloeschung; |
'K' : flag := dataSys.bKommentieren; |
'B' : flag := dataSys.bAntworten; |
'C' : flag := dataSys.bUser1; |
'X' : flag := dataSys.bUser2; |
'V' : flag := dataSys.bVererben; |
ELSE
doInvert := FALSE;
END;
IF doInvert
THEN
InternalInvert (ptr, flag);
RETURN TRUE;
END;
IF (scan # spaceScan)
& (scan # pointScan)
THEN
(* Andere Tasten mit Alt werden hier nicht mehr behandelt
*)
RETURN FALSE
END;
END; (* IF withAlt *)
done := TRUE;
CASE scan OF
escScan : IF ~withShift
THEN
msgList.listOpen (mess.Gruppe, mess.MailNr, win, mode);
ELSE
msgList.listOpen (mess.Gruppe, mess.MailNr, win, mOther);
END
|
undoScan : IF ptr^.undoGroup = ptr^.mess.Gruppe
THEN
SwitchTo(ptr, ptr^.undoPos, dJump, TRUE);
ELSE
IF ~isInSearch
THEN
SwitchToNewGroup(ptr^.undoGroup, ptr^.undoPos, ptr);
ELSE
CatGlobal.Bing (0);
END;
END; |
backspaceScan:
IF CatEdit.BlockIsMarked (win)
THEN
CatEdit.ClearBlock (win);
END; |
tabScan: msgList.listRemoveTree (listHdl, win, mess.MailNr, withShift); |
insertScan: (* Neuen Namen in Adressenliste eintragen *)
IF ptr^.mess.EigeneNachricht
THEN
MagicStrings.Assign (ptr^.mess.Empfaenger^, tmpName);
res := mtAlerts.Alert (1, MTE.saveName2);
ELSE
MagicStrings.Assign (ptr^.mess.Absender^, tmpName);
res := mtAlerts.Alert (1, MTE.saveName);
END;
IF res = 1
THEN
ListHelp.NewNameEntry (tmpName, '');
IF ConfVars.GetConfigBool (cSortNames, v.bool) & v.bool
THEN
data.SortList (data.names);
END;
END; |
fiveScan,
nullScan: SwitchTo(ptr, lastPos, dReturn, FALSE);
ELSE
done := FALSE;
END;
IF done THEN RETURN TRUE END;
done := TRUE;
CASE scan OF
pointScan,
spaceScan : (* Space *)
IF spacePaging & (kstate = {})
THEN
(* eventuell pagen *)
WdwManager.GetWdwDocument (win, doc);
WdwManager.GetScrollParms (win, pageW, pageH, v.lint, v.lint);
IF doc.y < doc.h - pageH
THEN
WdwManager.PageDown (win);
RETURN TRUE;
END;
END;
(* Jetzt evtl. zur nchsten oder vorigen Nachricht *)
IF NextPrevPrivate (ptr, scan, newCh, kstate)
THEN
RETURN TRUE;
END;
(* Wenn wir immer noch hier sind, dann knnen wir einfach
* zur nchsten oder vorherigen Nachricht gehen
*)
IF withAlt
THEN
dir := dPrevMess;
ELSE
dir := dNextMess;
END; |
oneScan: dir := dPrevMess; |
twoScan: dir := dDownMess; |
threeScan: dir := dNextMess; |
eightScan: dir := dUpMess; |
fourScan: dir := dLeftMess; |
sixScan: dir := dRightMess;|
ELSE
done := FALSE;
END;
IF done
THEN
switch (ptr, dir, newWindow, withShift);
RETURN TRUE;
END;
(* Scancode-Auswertung abgeschlossen, jetzt nur noch normale Tasten
* Erstmal normale Bewegung
*)
done := TRUE;
CASE newCh OF
'+' : dir := dDownMess; |
'-' : dir := dUpMess; |
'<' : dir := dLeftMess; |
'>' : dir := dRightMess; |
'Z' :
IF (handle^.group = dataSys.private) &
(~mess.EigeneNachricht)
THEN
v.bool := CheckPersonal (ptr, newCh, kstate, v.bool);
dir := dNextMess;
ELSE
done := FALSE;
END; |
'N' : IF NextPrevPrivate (ptr, scan, newCh, kstate)
THEN
RETURN TRUE;
END;
dir := dNextMess; |
'L' : IF NextPrevPrivate (ptr, scan, newCh, kstate)
THEN
RETURN TRUE;
END;
dir := dPrevMess; |
ELSE
done := FALSE;
END;
IF done
THEN
switch (ptr, dir, newWindow, withShift);
RETURN TRUE;
END;
(* Jetzt kommen nur noch normale Funktionen, also auch nix mit Ctrl! *)
IF newWindow THEN RETURN FALSE; END;
(* Jetzt die brigen Funktionen *)
done := TRUE;
CASE newCh OF
'0' : SwitchTo(ptr, lastPos, dReturn, FALSE); |
'T' : treeList.treeOpen (ptr^.mess.Gruppe, ptr^.mess.MailNr, win); |
'G' : grinTools.Handle(ptr^.win, grinTools.otherGroup); |
'U' : (* Userinfo *)
ActualName (ptr^.win, tmpName);
IF withShift
THEN
WriteToClip (tmpName);
ELSE
Protokoll.SendHelp (tmpName);
END; |
'I' : (* Info umschalten *)
IF ptr^.viewHeader = vhNone
THEN
ptr^.viewHeader := vhFull;
ELSE
ptr^.viewHeader := vhNone;
END;
SwitchTo (ptr, ptr^.mess.MailNr, dNone, FALSE); |
'Q' : CatEdit.MarkMultiple (win); |
'R' : WITH ptr^.mess DO
GroupSelect.GroupName (Gruppe, gName);
IF EigeneNachricht & (Gruppe = dataSys.private)
THEN
MagicStrings.Assign (Empfaenger^, tmpName);
ELSE
MagicStrings.Assign (Absender^, tmpName);
END;
WiederVorlage.AddResub (gName, MailID^, tmpName, Betreff^, tauschDate);
IF (ptr^.handle^.group = dataSys.private) &
(~EigeneNachricht)
THEN
IF ConfVars.GetConfigBool (cPostponeResubs, v.bool) & v.bool
& (Status = 'N')
THEN
tmpChar := 'Z';
v.bool := CheckPersonal (ptr, tmpChar, {}, v.bool);
END;
END;
END; |
'C' : (* Nachricht kopieren *)
IF ptr^.handle^.group = dataSys.private
THEN
grinTools.Handle(ptr^.win, grinTools.copy)
END; |
'K' : IF ptr^.handle^.group = dataSys.private
THEN
IF ptr^.mess.EigeneNachricht THEN
MTE.info(MTE.noOwnCom);
ELSE
grinTools.Handle(ptr^.win, grinTools.answer);
END;
ELSE
grinTools.Handle(ptr^.win, grinTools.comment)
END; |
'B',
'P' : IF ptr^.mess.EigeneNachricht THEN
MTE.info(MTE.noOwnCom);
ELSE
grinTools.Handle(ptr^.win, grinTools.answer);
END; |
'X' : v.int := mtAlerts.Alert (1, MTE.killMsg);
IF v.int = 1
THEN
SendState(ptr^.mess.MailID^, 'X');
END; |
'E' : CatEdit.ToggleMode (win, CatEdit.effMode);
(* Get font *)
needRedraw := FALSE;
IF CatEdit.GetMode (win, CatEdit.effMode)
THEN
(* Mit Effekten, normaler Font *)
num := BinOps.HigherInt (number-1, 0);
Strings.Concat (cMsgFont, StrConv.IntToStr (num, 0), varName, v.bool);
ConfVars.GetConfDefInt (varName, iFont, 1);
Strings.Concat (cMsgSize, StrConv.IntToStr (num, 0), varName, v.bool);
ConfVars.GetConfDefInt (varName, iFontSize, 10);
CatEdit.SelectEditFont (win, iFont, iFontSize);
ELSE
(* Ohne Effekte, Tabellenfont *)
ConfVars.GetConfDefInt (cMsgAltFont, iFont, 1);
ConfVars.GetConfDefInt (cMsgAltSize, iFontSize, 10);
CatEdit.SelectEditFont (win, iFont, iFontSize);
END;
IF needRedraw
THEN
WdwManager.FullRedrawWdw (win);
END; |
'W' : IF (ptr^.handle^.group = dataSys.private) THEN
grinTools.Handle(ptr^.win, grinTools.pass);
END;
ELSE
done := FALSE;
END;
RETURN done;
END; (* WITH ptr^ DO *)
ELSE
RETURN FALSE
END;
END grinKey;
(*--- Userprozeduren --------------------------*)
PROCEDURE CloseGrinWin(w : INTEGER):BOOLEAN; FORWARD;
PROCEDURE FindNum () : INTEGER;
VAR i : INTEGER;
BEGIN
IF (globalNumber >= 0) &
~ (globalNumber IN grinNums)
THEN
INCL (grinNums, globalNumber);
i := globalNumber;
globalNumber := -1;
RETURN i
END;
FOR i := 0 TO 255 DO
IF ~(i IN grinNums) THEN INCL (grinNums, i); RETURN i; END;
END;
END FindNum;
PROCEDURE ClearNum (num : INTEGER);
BEGIN
EXCL (grinNums, num);
END ClearNum;
(*TYPE getNumberProc = PROCEDURE ((* dataHandle *) ADDRESS):CARDINAL;*)
PROCEDURE grinOpenMessage(gruppe, which : CARDINAL;
nextMess: grinNextMessProc; listHandle: LONGCARD;
mode : openMode): INTEGER;
(* Ein Messagefenster der <gruppe> mit der Msg-nr. <which> ffnen *)
PROCEDURE Standard(ptr : data.OneGroupHandle):CARDINAL;
BEGIN
RETURN which
END Standard;
BEGIN
RETURN grinOpenWithProc(gruppe, Standard, nextMess, listHandle, mode);
END grinOpenMessage;
(*$H+*)
PROCEDURE grinOpenWithProc(gruppe : CARDINAL; whichNumber : getNumberProc;
nextMess: grinNextMessProc; listHandle : LONGCARD;
mode : openMode): INTEGER;
(* Ein Messagefenster der gruppe <gruppe> an der Stelle ffnen, die von *)
(* der bergebenen Prozedur zurckgeliefert wird *)
(*$H= *)
VAR messPtr : oneWindowPtr;
handlePtr : handlePool.oneHandlePtr;
work : GrafBase.Rectangle;
varName : CatTypes.String255;
num : INTEGER;
wdw : INTEGER;
vhMode : INTEGER;
BEGIN
IF handlePool.BlankToList(messPtr, TSIZE(oneWindow), windows) THEN
IF handlePool.GetOneDatahandle(gruppe, handlePtr) THEN
messPtr^.handle := handlePtr;
messPtr^.nextMsg := nextMess;
messPtr^.listHdl := listHandle;
messPtr^.lastLine := headerNone;
messPtr^.mode := mode;
messPtr^.readchange := FALSE;
messPtr^.treeMode := FALSE;
messPtr^.isLocked := FALSE;
messPtr^.inEvent := FALSE;
ConfVars.GetConfDefInt (cViewHeaderMode, vhMode, 0);
CASE vhMode OF
0 : messPtr^.viewHeader := vhNone; |
1 : messPtr^.viewHeader := vhFull;
ELSE
END;
IF GetOneMessage(messPtr, whichNumber(handlePtr^.Zugriff)) THEN (* Nachricht lesen *)
MakeTitle(messPtr);
WITH messPtr^ DO
win := -1;
inObjcDraw := FALSE;
(* Ein paar neue Zeilen *)
number := FindNum ();
Strings.Concat (cMsgWindow, StrConv.IntToStr (number, 0), varName,
v.bool);
IF ~ConfVars.GetConfigRect (varName, work)
THEN
num := BinOps.HigherInt (number-1, 0);
Strings.Concat (cMsgWindow, StrConv.IntToStr (num, 0), varName, v.bool);
ConfVars.GetConfDefRect (varName, work, EditTypes.deskSize);
IF ~RectFuncs.RectEqual (work, EditTypes.deskSize)
THEN
INC (work.x, 2*mtAppl.CharWidth);
INC (work.y, mtAppl.CharHeight);
END;
Strings.Concat (cMsgFont, StrConv.IntToStr (num, 0), varName, v.bool);
ConfVars.GetConfDefInt (varName, font, 1);
Strings.Concat (cMsgSize, StrConv.IntToStr (num, 0), varName, v.bool);
ConfVars.GetConfDefInt (varName, fontSize, 10);
(* Und jetzt direkt wieder setzen *)
Strings.Concat (cMsgWindow, StrConv.IntToStr (number, 0), varName, v.bool);
v.bool := ConfVars.SetConfigRect (varName, work);
Strings.Concat (cMsgFont, StrConv.IntToStr (number, 0), varName, v.bool);
v.bool := ConfVars.SetConfigInt (varName, font);
Strings.Concat (cMsgSize, StrConv.IntToStr (number, 0), varName, v.bool);
v.bool := ConfVars.SetConfigInt (varName, fontSize);
ELSE
Strings.Concat (cMsgFont, StrConv.IntToStr (number, 0), varName, v.bool);
ConfVars.GetConfDefInt (varName, font, 1);
Strings.Concat (cMsgSize, StrConv.IntToStr (number, 0), varName, v.bool);
ConfVars.GetConfDefInt (varName, fontSize, 10);
END;
globalNumber := number;
IF CatEdit.OpenEditBuffer(title, info, FALSE,
viewBuff, viewLen,
(* mess.Text, LONG(mess.textLen), *)
viewAllocated, (* ~refSuppressed, *)
isEnriched,
font, fontSize, work,
TRUE,
ADDRESS(click), ADDRESS(getRect),
ADDRESS(draw), ADDRESS(CloseGrinWin),
ADDRESS(grinKey), ADDRESS(grinTop), ADDRESS(grinUntop),
ADDRESS (grinGetHeaderInfo),
win)
(* dorthin kommt das Fensterhandle im Erfolgsfall *)
THEN
(* DD-Server anmelden *)
CatEdit.InstallUserDD (win, grinDDGetMaxExts,
grinDDGetExt,
grinDDGetExtName,
grinDDGetSize,
grinDDGetData);
(* jetzt im Editor, doppelt wg. Struktur *)
VDIStandards.StatusEnable (TRUE);
wdw := win;
(* Wenn refSuppressed TRUE ist, dann mssen wir hier den Speicher
* freigeben
*)
IF refSuppressed & (originalText # NIL)
THEN
DEALLOCATE(originalText, 0);
refSuppressed := FALSE;
ELSE
IF viewAllocated
THEN
DEALLOCATE (mess.Text, 0);
END;
END;
Protokoll.SendNewMsgInWdw();
IF (dataSys.bComToOwnMessage IN mess.StatusBits) OR
(dataSys.bOldComToOwnMessage IN mess.StatusBits)
(*
OR (dataSys.bOwnMessage IN mess.StatusBits)
*)
THEN
CatGlobal.Bing (0);
END;
ELSE
IF refSuppressed & (originalText # NIL)
THEN
DEALLOCATE(originalText, 0);
refSuppressed := FALSE;
ELSE
IF viewAllocated
THEN
DEALLOCATE(mess.Text, 0);
END;
END;
(* vorher:
DEALLOCATE(mess.Text, LONG(mess.textLen));
*)
ClearNum (number); (* <=== NEU! *)
msgList.listUnlockWdw (listHdl);
handlePool.FreeOneDataHandle(handlePtr);
handlePool.FreeOnePtr(messPtr, windows);
wdw := -1;
END;
globalNumber := -1;
lastPos := mess.MailNr;
undoPos := mess.MailNr;
undoGroup := gruppe;
undoTreeRoot := mess.MailNr;
data.SetLastReadMsg(handle^.group, mess.MailNr);
RETURN wdw;
END;
ELSE
msgList.listUnlockWdw (messPtr^.listHdl);
handlePool.FreeOneDataHandle(handlePtr);
handlePool.FreeOnePtr(messPtr, windows);
(* Wer macht die Fehlermeldung..? *)
MTE.info(MTE.noFound); (* ich *)
END;
ELSE
msgList.listUnlockWdw (messPtr^.listHdl);
handlePool.FreeOnePtr(messPtr, windows);
MTE.noMemAlert();
END;
ELSE
MTE.noMemAlert();
END;
RETURN -1;
END grinOpenWithProc;
(* grinOpenHeader fehlt noch, kommt, sobald das Grundgerst steht *)
PROCEDURE ClosePtr(p : oneWindowPtr);
VAR varName : CatTypes.String255;
full : GrafBase.Rectangle;
BEGIN
setReadFlag(p);
WITH p^ DO
Strings.Concat (cMsgWindow, StrConv.IntToStr (number, 0), varName, v.bool);
WdwManager.GetWdwSize (win, full); (* Gre des Fensters abfragen *)
v.bool := ConfVars.SetConfigRect (varName, full);
Strings.Concat (cMsgFont, StrConv.IntToStr (number, 0), varName, v.bool);
v.bool := ConfVars.SetConfigInt (varName, font);
Strings.Concat (cMsgSize, StrConv.IntToStr (number, 0), varName, v.bool);
v.bool := ConfVars.SetConfigInt (varName, fontSize);
ClearNum (number);
END;
msgList.listUnlockWdw (p^.listHdl);
handlePool.FreeOneDataHandle(p^.handle);
DEALLOCATE(p^.mess.InfoStrings, 0);
IF p^.treeMode THEN DEALLOCATE(p^.stack, 0); END;
handlePool.FreeOnePtr(p, windows);
END ClosePtr;
(*$Z+*)
PROCEDURE CloseGrinWin(win : INTEGER): BOOLEAN;
(*$Z=*)
VAR p : oneWindowPtr;
BEGIN
IF handlePool.FindEntry(ADR(win), FindWinCond, windows, p) THEN
IF p^.isLocked
THEN
(* Suche luft, nicht schlieen! *)
RETURN FALSE
END;
ClosePtr(p)
END;
RETURN TRUE;
END CloseGrinWin;
PROCEDURE grinClose(win : INTEGER); (* exportet *)
VAR p : oneWindowPtr;
BEGIN
IF handlePool.FindEntry(ADR(win), FindWinCond, windows, p) THEN
CatEdit.CloseEditBuffer(win)
END;
END grinClose;
PROCEDURE GetWdwFont (wdw: INTEGER; VAR iFont, iFontSize : INTEGER);
(* Holt den eingestellten Font *)
VAR p : oneWindowPtr;
varName : CatTypes.String255;
BEGIN
IF handlePool.FindEntry(ADR(wdw), FindWinCond, windows, p) THEN
WITH p^ DO
Strings.Concat (cMsgFont, StrConv.IntToStr (number, 0), varName, v.bool);
ConfVars.GetConfDefInt (varName, iFont, 1);
Strings.Concat (cMsgSize, StrConv.IntToStr (number, 0), varName, v.bool);
ConfVars.GetConfDefInt (varName, iFontSize, 10);
END;
END;
END GetWdwFont;
PROCEDURE GetAlternativeFont (VAR font, fontSize : INTEGER);
(* Holt den alternativen Font *)
BEGIN
ConfVars.GetConfDefInt (cMsgAltFont, font, 1);
ConfVars.GetConfDefInt (cMsgAltSize, fontSize, 10);
END GetAlternativeFont;
PROCEDURE grinWithEffects (win: INTEGER): BOOLEAN;
(* Gibt zurck, ob momentan Effekte angezeigt werden oder nicht
*)
VAR p : oneWindowPtr;
varName : CatTypes.String255;
BEGIN
IF handlePool.FindEntry(ADR(win), FindWinCond, windows, p) THEN
RETURN CatEdit.GetMode (win, CatEdit.effMode);
END;
RETURN FALSE;
END grinWithEffects;
PROCEDURE grinSetAlternativeFont (win, iFont, iFontSize : INTEGER);
(* Setzt den Font fr das Anzeigefenster *)
VAR p : oneWindowPtr;
varName : CatTypes.String255;
BEGIN
IF handlePool.FindEntry(ADR(win), FindWinCond, windows, p) THEN
(* p^.font := font; *)
(* p^.fontSize := fontSize; *)
WITH p^ DO
v.bool := ConfVars.SetConfigInt (cMsgAltFont, iFont);
v.bool := ConfVars.SetConfigInt (cMsgAltSize, iFontSize);
END;
IF ~CatEdit.GetMode (win, CatEdit.effMode)
THEN
CatEdit.SelectEditFont (win, iFont, iFontSize);
END;
END;
END grinSetAlternativeFont;
PROCEDURE grinSetFont (win, iFont, iFontSize : INTEGER);
(* Setzt den Font fr das Anzeigefenster *)
VAR p : oneWindowPtr;
varName : CatTypes.String255;
BEGIN
IF handlePool.FindEntry(ADR(win), FindWinCond, windows, p) THEN
p^.font := iFont;
p^.fontSize := iFontSize;
WITH p^ DO
Strings.Concat (cMsgFont, StrConv.IntToStr (number, 0), varName, v.bool);
v.bool := ConfVars.SetConfigInt (varName, font);
Strings.Concat (cMsgSize, StrConv.IntToStr (number, 0), varName, v.bool);
v.bool := ConfVars.SetConfigInt (varName, fontSize);
END;
IF CatEdit.GetMode (win, CatEdit.effMode)
THEN
CatEdit.SelectEditFont (win, iFont, iFontSize);
END;
END;
END grinSetFont;
PROCEDURE grinSavePos();
(* Sichert die Positionen aller grin-Fenster *)
VAR lauf : oneWindowPtr;
varName : ARRAY [0..255] OF CHAR;
full : GrafBase.Rectangle;
BEGIN
Lists.ResetList(windows);
lauf := Lists.NextEntry(windows);
WHILE lauf # NIL DO
WITH lauf^ DO
Strings.Concat (cMsgGroup, StrConv.IntToStr (number, 0), varName, v.bool);
v.bool := ConfVars.SetConfigLongInt (varName, VAL(LONGINT, mess.Gruppe));
Strings.Concat (cMsgMessage, StrConv.IntToStr (number, 0), varName, v.bool);
v.bool := ConfVars.SetConfigLongInt (varName, VAL(LONGINT, mess.MailNr));
Strings.Concat (cMsgWindow, StrConv.IntToStr (number, 0), varName, v.bool);
WdwManager.GetWdwSize (win, full); (* Gre des Fensters abfragen *)
v.bool := ConfVars.SetConfigRect (varName, full);
Strings.Concat (cMsgFont, StrConv.IntToStr (number, 0), varName, v.bool);
v.bool := ConfVars.SetConfigInt (varName, font);
Strings.Concat (cMsgSize, StrConv.IntToStr (number, 0), varName, v.bool);
v.bool := ConfVars.SetConfigInt (varName, fontSize);
END;
lauf := Lists.NextEntry(windows);
END;
END grinSavePos;
PROCEDURE grinRestorePos();
VAR varName : ARRAY [0..255] OF CHAR;
number : INTEGER;
gruppe,
mailNr : CARDINAL;
BEGIN
FOR number := 0 TO 255 DO
Strings.Concat (cMsgGroup, StrConv.IntToStr (number, 0), varName, v.bool);
IF ConfVars.GetConfigLongInt (varName, v.lint)
THEN
gruppe := VAL (CARDINAL, v.lint);
Strings.Concat (cMsgMessage, StrConv.IntToStr (number, 0), varName, v.bool);
IF ConfVars.GetConfigLongInt (varName, v.lint)
THEN
mailNr := VAL (CARDINAL, v.lint);
globalNumber := number;
v.int := grinOpenMessage (gruppe, mailNr, grinNextMess, 0, mOther);
END;
END;
END;
globalNumber := -1;
END grinRestorePos;
(*
PROCEDURE grinWindowEvent(pBuff : ADDRESS):BOOLEAN;
(* Diejenigen Windowevents behandeln, die vom Modul beachtet oder
* abgefangen werden mssen; Bei TRUE wurde das event komplett behandelt.
*)
VAR mBuff : POINTER TO ARRAY[0..7] OF INTEGER;
p : oneWindowPtr;
BEGIN
mBuff := pBuff;
IF handlePool.FindEntry(ADR(mBuff^[3]), FindWinCond, windows, p) THEN
IF (mBuff^[0] = MagicAES.WMSIZED) OR (mBuff^[0] = MagicAES.WMMOVED) THEN
AdjustPosition(mBuff^[4], mBuff^[5], mBuff^[6]);
END;
END;
RETURN FALSE
END grinWindowEvent;
*)
PROCEDURE grinCloseAll(); (* exportet *)
(* Alle Fenster schlieen *)
VAR lauf : oneWindowPtr;
BEGIN
Lists.ResetList(windows);
lauf := Lists.NextEntry(windows);
WHILE lauf # NIL DO
grinClose(lauf^.win);
lauf := Lists.NextEntry(windows);
END;
END grinCloseAll;
PROCEDURE grinWindowTop(win : INTEGER):BOOLEAN; (* exportet *)
(* Ist ein Anzeigefenster das oberste? *)
BEGIN
RETURN handlePool.FindEntry(ADR(win), FindWinCond, windows, v.a);
END grinWindowTop;
(* Auskunftprozeduren *)
PROCEDURE ActualSubject(win : INTEGER; VAR subject : ARRAY OF CHAR);
VAR ptr : oneWindowPtr;
BEGIN
IF handlePool.FindEntry(ADR(win), FindWinCond, windows, ptr) THEN
MagicStrings.Assign(ptr^.mess.Betreff^, subject);
ELSE
subject[0] := 0C;
END;
END ActualSubject;
PROCEDURE ActualID(win : INTEGER; VAR ID : ARRAY OF CHAR);
VAR ptr : oneWindowPtr;
BEGIN
IF handlePool.FindEntry(ADR(win), FindWinCond, windows, ptr) THEN
MagicStrings.Assign(ptr^.mess.MailID^, ID);
ELSE
ID[0] := 0C;
END;
END ActualID;
PROCEDURE ActualMId(win : INTEGER; VAR ID : ARRAY OF CHAR);
VAR ptr : oneWindowPtr;
BEGIN
IF handlePool.FindEntry(ADR(win), FindWinCond, windows, ptr) THEN
MagicStrings.Assign(ptr^.mess.mid^, ID);
ELSE
ID[0] := 0C;
END;
END ActualMId;
PROCEDURE ActualSender(win : INTEGER; VAR sender : ARRAY OF CHAR);
VAR ptr : oneWindowPtr;
BEGIN
IF handlePool.FindEntry(ADR(win), FindWinCond, windows, ptr) THEN
IF ptr^.mess.sender # NIL
THEN
MagicStrings.Assign (ptr^.mess.sender^, sender);
END;
ELSE
sender[0] := 0C;
END;
END ActualSender;
PROCEDURE ActualWdwName (win : INTEGER; VAR sender : ARRAY OF CHAR);
VAR ptr : oneWindowPtr;
BEGIN
IF handlePool.FindEntry(ADR(win), FindWinCond, windows, ptr) THEN
IF (ptr^.mess.EigeneNachricht) & (ptr^.mess.Gruppe = dataSys.private)
THEN
MagicStrings.Assign (ptr^.mess.Empfaenger^, sender);
ELSE
IF ptr^.mess.name^[0] = 0C THEN
MagicStrings.Assign (ptr^.mess.Absender^, sender);
ELSE
MagicStrings.Assign (ptr^.mess.name^, sender);
END;
END;
ELSE
sender[0] := 0C;
END;
END ActualWdwName;
PROCEDURE ActualFrom (win : INTEGER; VAR sender : ARRAY OF CHAR);
VAR ptr : oneWindowPtr;
BEGIN
IF handlePool.FindEntry(ADR(win), FindWinCond, windows, ptr) THEN
MagicStrings.Assign (ptr^.mess.Absender^, sender);
ELSE
sender[0] := 0C;
END;
END ActualFrom;
PROCEDURE ActualReplyto (win : INTEGER; VAR sender : ARRAY OF CHAR);
CONST cReplyTo = 'Reply-To:';
VAR ptr : oneWindowPtr;
line: ARRAY [0..511] OF CHAR;
lineAnf : ARRAY [0..40] OF CHAR;
l : CARDINAL;
BEGIN
sender[0] := 0C;
IF handlePool.FindEntry(ADR(win), FindWinCond, windows, ptr) THEN
IF ptr^.mess.replyTo # NIL
THEN
MagicStrings.Assign(ptr^.mess.replyTo^, sender);
END;
IF sender[0] = 0C
THEN
(* Im Text nachsehen *)
IF CatEdit.GetTextLine (ptr^.win, 0, line, v.int)
THEN
MagicStrings.Assign (line, lineAnf);
lineAnf[LENGTH(cReplyTo)] := '';
IF AssFuncs.StrIequal (cReplyTo, lineAnf)
THEN
MagicStrings.Delete (line, 0, LENGTH (cReplyTo));
Strings.DelLeadingBlanks (line);
MagicStrings.Assign (line, sender);
(* Steuerzeichen am Ende entfernen *)
l := LENGTH (sender);
WHILE (l > 0) & (ORD(sender[l-1]) < ORD(' ')) DO
DEC (l); sender[l] := '';
END;
END;
END;
END;
END;
END ActualReplyto;
PROCEDURE ActualName (win : INTEGER; VAR name : ARRAY OF CHAR);
VAR ptr : oneWindowPtr;
BEGIN
IF handlePool.FindEntry(ADR(win), FindWinCond, windows, ptr) THEN
IF (ptr^.mess.name # NIL) & (ptr^.mess.name^[0] = '')
THEN
MagicStrings.Assign(ptr^.mess.Absender^, name);
ELSIF (ptr^.mess.name # NIL)
THEN
MagicStrings.Assign(ptr^.mess.name^, name);
ELSE
name[0] := 0C;
END;
ELSE
name[0] := 0C;
END;
END ActualName;
PROCEDURE ActualReceiver(win : INTEGER; VAR receiver : ARRAY OF CHAR);
VAR ptr : oneWindowPtr;
BEGIN
IF handlePool.FindEntry(ADR(win), FindWinCond, windows, ptr) THEN
IF ptr^.mess.Empfaenger # NIL
THEN
MagicStrings.Assign(ptr^.mess.Empfaenger^, receiver);
ELSE
receiver[0] := 0C;
END;
ELSE
receiver[0] := 0C;
END;
END ActualReceiver;
PROCEDURE ActualGroup(win : INTEGER; VAR group : ARRAY OF CHAR);
VAR ptr : oneWindowPtr;
BEGIN
IF handlePool.FindEntry(ADR(win), FindWinCond, windows, ptr) THEN
GroupSelect.GroupName(ptr^.handle^.group, group);
ELSE
group[0] := 0C;
END;
END ActualGroup;
PROCEDURE ActualDist (win : INTEGER; VAR dist: data.tDistribution);
VAR ptr : oneWindowPtr;
BEGIN
IF handlePool.FindEntry(ADR(win), FindWinCond, windows, ptr) THEN
dist := ptr^.mess.distribution;
ELSE
dist := data.dNone;
END;
END ActualDist;
PROCEDURE ActualGroupNr(win : INTEGER):CARDINAL;
VAR ptr : oneWindowPtr;
BEGIN
IF handlePool.FindEntry(ADR(win), FindWinCond, windows, ptr) THEN
RETURN ptr^.handle^.group
ELSE
RETURN dataSys.maxGroup+1
END;
END ActualGroupNr;
PROCEDURE ActualRefId (win: INTEGER; VAR id: ARRAY OF CHAR);
VAR ptr : oneWindowPtr;
BEGIN
IF handlePool.FindEntry(ADR(win), FindWinCond, windows, ptr) THEN
MagicStrings.Assign (ptr^.mess.KommentierteID, id);
ELSE
id[0] := 0C;
END;
END ActualRefId;
PROCEDURE ActualRId (win: INTEGER; VAR id: ARRAY OF CHAR);
VAR ptr : oneWindowPtr;
BEGIN
IF handlePool.FindEntry(ADR(win), FindWinCond, windows, ptr) THEN
IF ptr^.mess.rid # NIL
THEN
MagicStrings.Assign(ptr^.mess.rid^, id);
ELSE
id[0] := 0C;
END;
ELSE
id[0] := 0C;
END;
END ActualRId;
PROCEDURE ActualFollowup (win: INTEGER; VAR id: ARRAY OF CHAR);
VAR ptr : oneWindowPtr;
BEGIN
IF handlePool.FindEntry(ADR(win), FindWinCond, windows, ptr) THEN
IF ptr^.mess.followupTo # NIL
THEN
MagicStrings.Assign(ptr^.mess.followupTo^, id);
ELSE
id[0] := 0C;
END;
ELSE
id[0] := 0C;
END;
END ActualFollowup;
PROCEDURE ActualDate (win: INTEGER; VAR date: ConvertDate.Date;
VAR time: ConvertDate.Time);
VAR ptr : oneWindowPtr;
BEGIN
IF handlePool.FindEntry(ADR(win), FindWinCond, windows, ptr)
THEN
ConvertDate.CatDate2Datim (ptr^.mess.tauschDate, date, time);
ELSE
Block.Clear (ADR(date), SIZE(date));
Block.Clear (ADR(time), SIZE(time));
END;
END ActualDate;
PROCEDURE ActualStatusDate (win: INTEGER; VAR date: ConvertDate.Date;
VAR time: ConvertDate.Time);
VAR ptr : oneWindowPtr;
BEGIN
IF handlePool.FindEntry(ADR(win), FindWinCond, windows, ptr)
THEN
ConvertDate.CatDate2Datim (ptr^.mess.statusDate, date, time);
ELSE
Block.Clear (ADR(date), SIZE(date));
Block.Clear (ADR(time), SIZE(time));
END;
END ActualStatusDate;
PROCEDURE ActualIsOwn (win: INTEGER; VAR isOwn: BOOLEAN);
VAR ptr : oneWindowPtr;
BEGIN
IF handlePool.FindEntry(ADR(win), FindWinCond, windows, ptr)
THEN
isOwn := ptr^.mess.EigeneNachricht;
ELSE
isOwn := FALSE;
END;
END ActualIsOwn;
PROCEDURE ActualText (win: INTEGER; txtBuf: ADDRESS);
VAR ptr : oneWindowPtr;
BEGIN
IF handlePool.FindEntry(ADR(win), FindWinCond, windows, ptr) THEN
IF ptr^.viewBuff # NIL
THEN
Block.Copy (ptr^.viewBuff, ptr^.viewLen, txtBuf);
END;
END;
END ActualText;
PROCEDURE ActualOrgText (win: INTEGER; txtBuf: ADDRESS);
VAR ptr : oneWindowPtr;
tmpMess: data.MessageType;
BEGIN
IF handlePool.FindEntry(ADR(win), FindWinCond, windows, ptr)
THEN
data.ReadMessage (ptr^.handle^.Zugriff, ptr^.mess.MailNr, tmpMess);
IF tmpMess.InfoStrings # NIL
THEN
DEALLOCATE (tmpMess.InfoStrings, 0);
END;
IF tmpMess.Text # NIL
THEN
Block.Copy (tmpMess.Text, tmpMess.textLen, txtBuf);
DEALLOCATE (tmpMess.Text, 0);
END;
END;
END ActualOrgText;
PROCEDURE ActualInternalId (win: INTEGER; VAR Id: LONGCARD);
VAR ptr : oneWindowPtr;
tmpMess: data.MessageType;
BEGIN
IF handlePool.FindEntry(ADR(win), FindWinCond, windows, ptr)
THEN
Id := LONG(ptr^.mess.Gruppe) * 65536L + LONG(ptr^.mess.MailNr);
ELSE
Id := 0FFFFFFFFH;
END;
END ActualInternalId;
PROCEDURE ActualMime (win: INTEGER; VAR mime: ARRAY OF CHAR);
VAR ptr : oneWindowPtr;
BEGIN
IF handlePool.FindEntry(ADR(win), FindWinCond, windows, ptr) THEN
IF ptr^.mess.mime # NIL
THEN
MagicStrings.Assign(ptr^.mess.mime^, mime);
ELSE
mime[0] := 0C;
END;
ELSE
mime[0] := 0C;
END;
END ActualMime;
PROCEDURE ActualGate (win: INTEGER; VAR gate: ARRAY OF CHAR);
VAR ptr : oneWindowPtr;
BEGIN
IF handlePool.FindEntry(ADR(win), FindWinCond, windows, ptr) THEN
IF ptr^.mess.gate # NIL
THEN
MagicStrings.Assign(ptr^.mess.gate^, gate);
ELSE
gate[0] := 0C;
END;
ELSE
gate[0] := 0C;
END;
END ActualGate;
PROCEDURE ActualBox (win: INTEGER; VAR box: ARRAY OF CHAR);
VAR ptr : oneWindowPtr;
BEGIN
IF handlePool.FindEntry(ADR(win), FindWinCond, windows, ptr) THEN
IF ptr^.mess.box # NIL
THEN
MagicStrings.Assign(ptr^.mess.box^, box);
ELSE
box[0] := 0C;
END;
ELSE
box[0] := 0C;
END;
END ActualBox;
PROCEDURE ActualStatus (win: INTEGER; VAR status: ARRAY OF CHAR);
VAR ptr : oneWindowPtr;
BEGIN
IF handlePool.FindEntry(ADR(win), FindWinCond, windows, ptr) THEN
MagicStrings.Assign (ptr^.mess.Status, status);
ELSE
status[0] := 0C;
END;
END ActualStatus;
(* Grenabfragen *)
PROCEDURE CheckedLength (strPtr: CatTypes.Str255Ptr): LONGCARD;
BEGIN
IF strPtr = NIL THEN RETURN 0 END;
RETURN LONG (LENGTH (strPtr^));
END CheckedLength;
PROCEDURE ActSubjectSize (win: INTEGER) : LONGCARD;
VAR ptr : oneWindowPtr;
BEGIN
IF handlePool.FindEntry(ADR(win), FindWinCond, windows, ptr)
THEN
RETURN CheckedLength (ptr^.mess.Betreff);
END;
RETURN 0;
END ActSubjectSize;
PROCEDURE ActIdSize (win: INTEGER) : LONGCARD;
VAR ptr : oneWindowPtr;
BEGIN
IF handlePool.FindEntry(ADR(win), FindWinCond, windows, ptr)
THEN
RETURN CheckedLength (ptr^.mess.MailID);
END;
RETURN 0;
END ActIdSize;
PROCEDURE ActMIdSize (win: INTEGER) : LONGCARD;
VAR ptr : oneWindowPtr;
BEGIN
IF handlePool.FindEntry(ADR(win), FindWinCond, windows, ptr)
THEN
RETURN CheckedLength (ptr^.mess.mid);
END;
RETURN 0;
END ActMIdSize;
PROCEDURE ActSenderSize (win: INTEGER) : LONGCARD;
VAR ptr : oneWindowPtr;
BEGIN
IF handlePool.FindEntry(ADR(win), FindWinCond, windows, ptr)
THEN
RETURN CheckedLength (ptr^.mess.sender);
END;
RETURN 0;
END ActSenderSize;
PROCEDURE ActFromSize (win: INTEGER) : LONGCARD;
VAR ptr : oneWindowPtr;
BEGIN
IF handlePool.FindEntry(ADR(win), FindWinCond, windows, ptr)
THEN
RETURN CheckedLength (ptr^.mess.Absender);
END;
RETURN 0;
END ActFromSize;
PROCEDURE ActReceiverSize (win: INTEGER) : LONGCARD;
VAR ptr : oneWindowPtr;
BEGIN
IF handlePool.FindEntry(ADR(win), FindWinCond, windows, ptr)
THEN
RETURN CheckedLength (ptr^.mess.Empfaenger);
END;
RETURN 0;
END ActReceiverSize;
PROCEDURE ActGroupSize (win: INTEGER) : LONGCARD;
VAR ptr : oneWindowPtr;
name: CatTypes.String255;
BEGIN
IF handlePool.FindEntry(ADR(win), FindWinCond, windows, ptr)
THEN
GroupSelect.GroupName(ptr^.handle^.group, name);
RETURN LONG (LENGTH (name));
END;
RETURN 0;
END ActGroupSize;
PROCEDURE ActWdwNameSize (win: INTEGER) : LONGCARD;
VAR ptr : oneWindowPtr;
name: CatTypes.String1023;
BEGIN
IF handlePool.FindEntry(ADR(win), FindWinCond, windows, ptr)
THEN
ActualWdwName (win, name);
RETURN LONG (LENGTH (name));
END;
RETURN 0;
END ActWdwNameSize;
PROCEDURE ActNameSize (win: INTEGER) : LONGCARD;
VAR ptr : oneWindowPtr;
name: CatTypes.String1023;
BEGIN
IF handlePool.FindEntry(ADR(win), FindWinCond, windows, ptr)
THEN
ActualName (win, name);
RETURN LONG (LENGTH (name));
END;
RETURN 0;
END ActNameSize;
PROCEDURE ActReplyToSize (win: INTEGER) : LONGCARD;
VAR ptr : oneWindowPtr;
name: CatTypes.String1023;
BEGIN
IF handlePool.FindEntry(ADR(win), FindWinCond, windows, ptr)
THEN
ActualReplyto (win, name);
RETURN LONG (LENGTH (name));
END;
RETURN 0;
END ActReplyToSize;
PROCEDURE ActRefIdSize (win: INTEGER) : LONGCARD;
VAR ptr : oneWindowPtr;
BEGIN
IF handlePool.FindEntry(ADR(win), FindWinCond, windows, ptr)
THEN
RETURN LONG (LENGTH (ptr^.mess.KommentierteID));
END;
RETURN 0;
END ActRefIdSize;
PROCEDURE ActRIdSize (win: INTEGER) : LONGCARD;
VAR ptr : oneWindowPtr;
BEGIN
IF handlePool.FindEntry(ADR(win), FindWinCond, windows, ptr)
THEN
RETURN CheckedLength (ptr^.mess.rid);
END;
RETURN 0;
END ActRIdSize;
PROCEDURE ActFollowupSize (win: INTEGER) : LONGCARD;
VAR ptr : oneWindowPtr;
BEGIN
IF handlePool.FindEntry(ADR(win), FindWinCond, windows, ptr)
THEN
RETURN CheckedLength (ptr^.mess.followupTo);
END;
RETURN 0;
END ActFollowupSize;
PROCEDURE ActDistSize (win: INTEGER) : LONGCARD;
VAR ptr : oneWindowPtr;
BEGIN
IF handlePool.FindEntry(ADR(win), FindWinCond, windows, ptr)
THEN
RETURN 2;
END;
RETURN 0;
END ActDistSize;
PROCEDURE ActStatusSize (win: INTEGER) : LONGCARD;
VAR ptr : oneWindowPtr;
BEGIN
IF handlePool.FindEntry(ADR(win), FindWinCond, windows, ptr)
THEN
RETURN 2;
END;
RETURN 0;
END ActStatusSize;
PROCEDURE ActDateSize (win: INTEGER) : LONGCARD;
VAR ptr : oneWindowPtr;
BEGIN
IF handlePool.FindEntry(ADR(win), FindWinCond, windows, ptr)
THEN
RETURN 4;
END;
RETURN 0;
END ActDateSize;
PROCEDURE ActStatusDateSize (win: INTEGER) : LONGCARD;
VAR ptr : oneWindowPtr;
BEGIN
IF handlePool.FindEntry(ADR(win), FindWinCond, windows, ptr)
THEN
RETURN 4;
END;
RETURN 0;
END ActStatusDateSize;
PROCEDURE ActTextSize (win: INTEGER) : LONGCARD;
VAR ptr : oneWindowPtr;
BEGIN
IF handlePool.FindEntry(ADR(win), FindWinCond, windows, ptr)
THEN
RETURN ptr^.viewLen;
END;
RETURN 0;
END ActTextSize;
PROCEDURE ActOrgTextSize (win: INTEGER) : LONGCARD;
VAR ptr : oneWindowPtr;
tmpMess: data.MessageType;
BEGIN
IF handlePool.FindEntry(ADR(win), FindWinCond, windows, ptr)
THEN
data.ReadHeader (ptr^.handle^.Zugriff, ptr^.mess.MailNr, tmpMess);
IF tmpMess.InfoStrings # NIL
THEN
DEALLOCATE (tmpMess.InfoStrings, 0);
RETURN tmpMess.textLen;
END;
END;
RETURN 0;
END ActOrgTextSize;
PROCEDURE ActMimeSize (win: INTEGER) : LONGCARD;
VAR ptr : oneWindowPtr;
BEGIN
IF handlePool.FindEntry(ADR(win), FindWinCond, windows, ptr)
THEN
RETURN CheckedLength (ptr^.mess.mime);
END;
RETURN 0;
END ActMimeSize;
PROCEDURE ActGateSize (win: INTEGER) : LONGCARD;
VAR ptr : oneWindowPtr;
BEGIN
IF handlePool.FindEntry(ADR(win), FindWinCond, windows, ptr)
THEN
RETURN CheckedLength (ptr^.mess.gate);
END;
RETURN 0;
END ActGateSize;
PROCEDURE ActBoxSize (win: INTEGER) : LONGCARD;
VAR ptr : oneWindowPtr;
BEGIN
IF handlePool.FindEntry(ADR(win), FindWinCond, windows, ptr)
THEN
RETURN CheckedLength (ptr^.mess.box);
END;
RETURN 0;
END ActBoxSize;
PROCEDURE ActIsOwnSize (win: INTEGER) : LONGCARD;
VAR ptr : oneWindowPtr;
BEGIN
IF handlePool.FindEntry(ADR(win), FindWinCond, windows, ptr)
THEN
RETURN 2;
END;
RETURN 0;
END ActIsOwnSize;
PROCEDURE ActInternalIdSize (win: INTEGER) : LONGCARD;
VAR ptr : oneWindowPtr;
BEGIN
IF handlePool.FindEntry(ADR(win), FindWinCond, windows, ptr)
THEN
RETURN 4;
END;
RETURN 0;
END ActInternalIdSize;
PROCEDURE InvertStatus(topWin : INTEGER; whichState : CARDINAL);
(* Invertiert den angegebenen Status, entsprechende Konstanten sind in data.d zu finden *)
VAR ptr : oneWindowPtr;
BEGIN
IF handlePool.FindEntry(ADR(topWin), FindWinCond, windows, ptr) THEN
InternalInvert(ptr, whichState);
END;
END InvertStatus;
PROCEDURE newStatus(topWin : INTEGER; clear, set : BITSET);
VAR ptr : oneWindowPtr;
BEGIN
IF handlePool.FindEntry(ADR(topWin), FindWinCond, windows, ptr) THEN
CLEARBITS := clear; SETBITS := set;
InternalChange(ptr, newBits);
END;
END newStatus;
PROCEDURE grinNewState(TopWin : INTEGER; newState : CHAR);
VAR ptr : oneWindowPtr;
BEGIN
IF handlePool.FindEntry(ADR(TopWin), FindWinCond, windows, ptr) &
(ptr^.handle^.group = dataSys.private) THEN
changeState(ptr, newState);
END;
END grinNewState;
(* = (sUBERALL, sTEXT, sBETREFF, sTEXTnBETREFF, sABSENDER, sEMPFAENGER, sID); *)
PROCEDURE SearchMenu(topWin : INTEGER);
VAR res : INTEGER;
BEGIN
res := ZSearchDial.DoSearchDial(FALSE);
IF res = ZSearchDial.FASTAHEAD THEN
DoSearch(topWin, TRUE);
ELSIF res = ZSearchDial.FASTBACK THEN
DoSearch(topWin, FALSE);
END;
END SearchMenu;
PROCEDURE DoSearch(topWin : INTEGER; forward : BOOLEAN);
VAR nr : CARDINAL;
ptr : oneWindowPtr;
what : data.SearchSet;
s : CARDINAL;
found : BOOLEAN;
noMore : BOOLEAN;
break : BOOLEAN;
handle : handlePool.oneHandlePtr;
which : CARDINAL;
gAnz : CARDINAL;
gNr : CARDINAL;
BEGIN
IF isInSearch THEN RETURN END;
isInSearch := TRUE;
IF suchVar.searchStr[0,0] = 0C THEN
suchVar.searchText := FALSE;
END;
IF ~handlePool.FindEntry(ADR(topWin), FindWinCond, windows, ptr) OR
~(suchVar.searchText OR suchVar.statussearch)
THEN
isInSearch := FALSE;
RETURN
END;
what := data.SearchSet{};
IF suchVar.statussearch THEN INCL(what, data.inBits) END;
IF suchVar.searchText THEN INCL(what, data.inText) END;
IF ~suchVar.show THEN INCL(what, data.dontShow) END;
IF suchVar.change THEN INCL(what, data.changeBits) END;
IF ~forward THEN INCL(what, data.reverse) END;
IF suchVar.ask THEN INCL(what, data.ask) END;
(* ask wird noch nicht beachtet *)
IF forward THEN
s := ptr^.mess.MailNr+1; (* StartNachricht *)
ELSE
s := ptr^.mess.MailNr;
IF s = 0 THEN
isInSearch := FALSE;
RETURN
ELSE DEC(s) END;
END;
found := FALSE;
noMore := FALSE;
break := FALSE;
gNr := ptr^.handle^.group;
v.bool := GroupSelect.GroupNumber('$&%$&%$/&/&%&/$&/Ý$/&$/&', gAnz);
ptr^.isLocked := TRUE;
WHILE ~break & (gNr # dataSys.empty) & ~found & ~stopSearch() & ~noMore DO
IF handlePool.GetOneDatahandle(gNr, handle) THEN
found := data.ComplexSearch(handle^.Zugriff,
s, (* StartNachricht *)
suchVar.sSetBits,
suchVar.sClearedBits, (* Zusammen Suchmaske *)
suchVar.searchStr[0], (* Zu suchender String *)
suchVar.searchStr[1], suchVar.searchStr[2], suchVar.searchStr[3],
suchVar.wo[0], suchVar.wo[1], suchVar.wo[2], suchVar.wo[3],
suchVar.verkn[0], suchVar.verkn[1], suchVar.verkn[2],
suchVar.gross, (* gro=klein? *)
suchVar.setBits,
suchVar.clearBits, (* Zusammen Setzmaske *)
what, (* Was machen? *)
break,
nr);
handlePool.FreeOneDataHandle(handle);
END;
IF ~found & suchVar.groupsearch THEN
IF forward THEN
gNr := GroupSelect.NextGroupNumber(gNr);
s := 0;
ELSE
gNr := GroupSelect.PreviousGroupNumber(gNr);
IF gNr <= dataSys.maxGroup THEN
s := data.LastMsgOfGroup(gNr);
ELSE
s := dataSys.empty;
END;
END;
ELSE
noMore := TRUE
END;
CatGlobal.busyMouse();
END;
mtAppl.MouseArrow();
ptr^.isLocked := FALSE;
IF found THEN
IF gNr # ptr^.handle^.group THEN
SwitchToNewGroup(gNr, nr, ptr);
ELSE
SwitchTo(ptr, nr, dJump, FALSE);
END;
IF suchVar.searchText
THEN
IF ~forward
THEN
v.bool := CatEdit.Search (topWin, suchVar.searchStr[0], EditTypes.fromStart, EditTypes.forward,
EditTypes.searchOne, 1, suchVar.gross, FALSE, FALSE);
ELSE
(* Noch im Anzeigeeditor suchen *)
v.bool := CatEdit.Search (topWin, suchVar.searchStr[0], EditTypes.fromStart, EditTypes.forward,
EditTypes.searchOne, 1, suchVar.gross, FALSE, FALSE);
END;
END;
IF suchVar.change & suchVar.ask THEN
IF mtAlerts.Alert(1, MTE.changeFlgs) = 1 THEN
SETBITS := suchVar.setBits; CLEARBITS := suchVar.clearBits;
InternalChange(ptr, newBits);
END;
END;
ELSE
(* Nichts gefunden *)
CatGlobal.Bing (7);
END;
isInSearch := FALSE;
END DoSearch;
PROCEDURE grinInfoline( msgWin : INTEGER; editWin : INTEGER; REF infoline : ARRAY OF CHAR);
VAR info,
ap : CatTypes.String255;
format : ARRAY [0..40] OF CHAR;
scrap : ARRAY[0..10] OF CHAR;
z, zz,
d, l,
ll : CARDINAL;
inStr,
other : BOOLEAN;
c : CHAR;
ptr : oneWindowPtr;
dt : ConvertDate.Date;
ti : ConvertDate.Time;
sex : GenderTest.Sex;
PROCEDURE GetFormat (REF s: ARRAY OF CHAR; VAR start: CARDINAL;
VAR form : ARRAY OF CHAR);
VAR p : CARDINAL;
BEGIN
p := MagicStrings.Pos (')', s, start, FALSE);
IF p < LENGTH (s)
THEN
MagicStrings.Copy (s, start, p-start, form);
start := p;
ELSE
MagicStrings.Assign ('', form);
END;
END GetFormat;
PROCEDURE RealName (VAR name: ARRAY OF CHAR);
BEGIN
WITH ptr^ DO
IF MagicStrings.Length (mess.name^) = 0
THEN
MagicStrings.Assign(mess.Absender^, name);
d := MagicStrings.Pos ('@', name, 0, FALSE);
IF d < LENGTH (name) THEN
name [d] := 0C; DEC (d);
WHILE (d>0) & (name[d] = ' ') DO
name[d] := 0C;
DEC (d);
END;
END;
ELSE
MagicStrings.Assign(mess.name^, name)
END;
END;
END RealName;
PROCEDURE SplitName (REF name: ARRAY OF CHAR; VAR firstName, lastName: ARRAY OF CHAR);
VAR p, lastP : INTEGER;
BEGIN
p := 0;
lastP := 0;
REPEAT
lastP := p;
IF p > 0 THEN INC (p); END;
p := Strings.Pos (" ", name, p);
UNTIL p < 0;
Strings.Copy (name, 0, lastP, firstName, v.bool);
Strings.Copy (name, lastP+1, INTEGER(LENGTH(name))-lastP-1, lastName, v.bool);
END SplitName;
PROCEDURE FirstName (VAR name: ARRAY OF CHAR);
VAR tmp : ARRAY [0..79] OF CHAR;
BEGIN
RealName (name);
SplitName (name, name, tmp);
END FirstName;
PROCEDURE LastName (VAR name: ARRAY OF CHAR);
VAR tmp : ARRAY [0..79] OF CHAR;
BEGIN
RealName (name);
SplitName (name, tmp, name);
END LastName;
BEGIN
IF handlePool.FindEntry(ADR( msgWin), FindWinCond, windows, ptr)
THEN
WITH ptr^ DO
l := MagicStrings.Length(infoline);
d := 0;
info := '';
inStr := FALSE;
z := 0;
WHILE z < l DO
IF ~inStr THEN
ap := '';
other := FALSE;
CASE MagicStrings.Cap (infoline[z]) OF
'U' : MagicStrings.Assign(mess.Absender^, ap) |
'D' : IF infoline[z+1] = '('
THEN
(* Mit Format! *)
INC (z,2);
GetFormat (infoline, z, format);
IF format[0] = '#'
THEN
c := format[1];
FOR zz := 0 TO 31 DO
format[zz] := c;
END;
format[32] := 0C;
END;
ConvertDate.CatDate2Datim (mess.tauschDate, dt, ti);
ConvertDate.DayToText (dt, format, ap);
ELSE
MagicStrings.Copy(mess.Datum, 0, 2, ap)
END; |
'T' : IF infoline[z+1] = '('
THEN
INC (z,2);
GetFormat (infoline, z, format);
ConvertDate.CatDate2Datim (mess.tauschDate, dt, ti);
ConvertDate.TimeToText (ti, format, ap);
ELSE
MagicStrings.Copy(mess.Datum, 13, 5, ap)
END; |
'A' : IF infoline[z+1] = '('
THEN
INC (z,2);
GetFormat (infoline, z, format);
ConvertDate.CatDate2Datim (mess.tauschDate, dt, ti);
ConvertDate.DateToText (dt, format, ap);
ELSE
MagicStrings.Copy(mess.Datum, 4, 8, ap)
END; |
'H' : IF infoline[z+1] = '('
THEN
INC (z,2);
GetFormat (infoline, z, format);
ELSE
MagicStrings.Assign ('G', format);
END;
ConvertDate.CatDate2Datim (mess.tauschDate, dt, ti);
ConvertDate.FuzzyTime (ti, format, ap); |
'F' : IF infoline[z+1] = '('
THEN
INC (z,2);
GetFormat (infoline, z, format);
ELSE
MagicStrings.Assign ('G', format);
END;
ConvertDate.CatDate2Datim (mess.tauschDate, dt, ti);
ConvertDate.FuzzyDate (dt, ti, format, ap); |
'G' : IF mess.Gruppe # dataSys.private THEN
GroupSelect.GroupName (mess.Gruppe, ap);
ELSIF mess.Gruppe = dataSys.private THEN
MagicStrings.Assign('persnliche Msg', ap)
END; |
'M' : MagicStrings.Assign(mess.MailID^, ap) |
'R' : RealName (ap); |
'V' : FirstName (ap); |
'N' : LastName (ap); |
'S' : FirstName (ap);
GenderTest.SexTest (ap, sex);
IF sex = GenderTest.female
THEN
MagicStrings.Assign (cFemale, ap)
ELSE
MagicStrings.Assign (cMale, ap)
END;
|
'I' : IF MagicStrings.Length (mess.mid^) = 0
THEN
MagicStrings.Assign(mess.MailID^, ap)
ELSE
MagicStrings.Assign (mess.mid^, ap)
END; |
'"',
"'" : inStr := ~inStr;
other := TRUE;
ELSE
ap[0] := infoline[z];
ap[1] := 0C;
other := TRUE;
END;
ELSE (* IF ~inStr *)
IF infoline[z] = '"' THEN
inStr := ~inStr;
ap := '';
ELSIF infoline[z] = "'" THEN
inStr := ~inStr;
ap := '';
ELSE
ap[0] := infoline[z];
ap[1] := 0C;
END;
END;
MagicStrings.Append(ap, info);
INC (z);
END;
MagicStrings.Append(CR, info);
MagicStrings.Append(LF, info);
IF (MagicStrings.Length(info) > 0) & CatEdit.IsEditTop(editWin) THEN
v.bool := CatEdit.QuoteSomething (editWin, '', ADR(info), LENGTH (info), -1);
END;
END;
END;
END grinInfoline;
PROCEDURE changeTree(win : INTEGER; clear, set : BITSET; all : BOOLEAN);
(* Baum mit durchlaufen, dabei die Flags clear lschen und set setzen *)
(* all - ganzer Baum, sonst nur runter *)
VAR ptr : oneWindowPtr;
BEGIN
IF handlePool.FindEntry(ADR(win), FindWinCond, windows, ptr) THEN
CLEARBITS := clear; SETBITS := set;
data.TreeFlags(ptr^.handle^.Zugriff, ptr^.mess.MailNr, all, flagupdate, newBits);
END;
END changeTree;
(* Fr die Protokolluntersttzung: *)
(*$? grinWindowProto:
PROCEDURE getAllWinds(adr : ADDRESS; maxAnz : INTEGER; VAR anz : INTEGER);
(* Schreibt alle offenen Anzeigefenster in den Speicher ab <adr> *)
(* Maximal <max> viele. Rckgabewert der geschriebenen in <anz>. *)
(* Sind es mehr als max, so ist dies die Anzahl der offenen Fenster *)
VAR cp : POINTER TO ARRAY[0..MAX(CARDINAL)] OF INTEGER;
(*$A+,Z-*)
PROCEDURE scanWinCond(e, i : ADDRESS):BOOLEAN;
(* Abbruchprozedur, wie in <Lists> gefordert *)
VAR p : oneWindowPtr;
BEGIN
IF e # NIL THEN
p := e;
IF anz < maxAnz THEN (* In die Tabelle eintragen, falls es noch pat *)
cp^[anz] := p^.win;
END;
INC(anz);
END;
RETURN FALSE
END scanWinCond;
(*$A=,Z=*)
BEGIN
anz := 0;
cp := adr;
Lists.ResetList(windows);
Lists.ScanEntries(windows, Lists.forward, scanWinCond, NIL, v.bool);
END getAllWinds;
PROCEDURE getPos(adr : ADDRESS; pos : INTEGER; win : INTEGER):CARDINAL;
(* Positionen zu einem Fenster abrufen: *)
(* 0 Neue, 1 letzte Position, 2 ab Datum, 3 ab Nummer, 4 erste ungelesene *)
(* bei 2 und 3 wird in adr die Adresse eines Strings bergeben. *)
VAR ptr : oneWindowPtr;
str : CatTypes.Str1023Ptr;
BEGIN
IF handlePool.FindEntry(ADR(win), FindWinCond, windows, ptr) THEN
str := adr;
CASE pos OF
0 : RETURN data.FirstNewMsg(ptr^.mess.Gruppe);
| 1 : RETURN data.lastReadMsgOfGroup(ptr^.mess.Gruppe);
| 2 : RETURN data.NumberOfID(ptr^.handle^.Zugriff, str^);
| 3 : RETURN data.NumberOfDate(ptr^.handle^.Zugriff, ConvertDate.StrToDate(str^));
| 4 : RETURN data.unreadMsgPos(ptr^.mess.Gruppe);
ELSE
RETURN 0FFFFH;
END;
ELSE
RETURN 0FFFFH;
END;
END getPos;
PROCEDURE switchMess(win : INTEGER; mess, group : CARDINAL):BOOLEAN;
(* Neue Msg in ein Fenster setzen; Fr das Protokoll *)
VAR ptr : oneWindowPtr;
BEGIN
IF handlePool.FindEntry(ADR(win), FindWinCond, windows, ptr) THEN
msgList.listUnlockWdw (ptr^.listHdl);
ptr^.listHdl := 0;
IF ptr^.mess.Gruppe = group THEN
SwitchTo (ptr, mess, dJump, FALSE);
ELSE
SwitchToNewGroup(group, mess, ptr);
END;
RETURN TRUE;
ELSE
RETURN FALSE;
END;
END switchMess;
PROCEDURE getInfo(win : INTEGER; adr : ADDRESS; amount : LONGCARD):BOOLEAN;
(* Die Infos zu diesem Fenster abholen. Geliefert wird: *)
(* ab <adr> steht ein data.MessageType. Direkt dahinter die Infostrings und *)
(* dahinter noch der eigentliche MsgText. Gibt zurck, ob es geklappt hat oder ob *)
(* das Fenster nicht mehr da ist bzw. die Information nicht gepat hat. *)
(* --- Ende der Protokollprozeduren --- *)
VAR ptr : oneWindowPtr;
a : ADDRESS;
m : POINTER TO data.MessageType;
pLC : POINTER TO LONGCARD;
BEGIN
IF handlePool.FindEntry(ADR(win), FindWinCond, windows, ptr) THEN
IF amount = 0
THEN
pLC := adr;
amount := pLC^;
INC (adr, 4);
IF amount = 0
THEN
RETURN FALSE
END;
END;
IF amount >= TSIZE(data.MessageType) + LONG(ptr^.mess.textLen) + LONG(ptr^.mess.infoLen) THEN
m := adr;
m^ := ptr^.mess;
a := adr + TSIZE(data.MessageType);
IF ODD(LONGCARD(a)) THEN INC(a) END;
Block.Copy(ptr^.mess.InfoStrings, LONG(ptr^.mess.infoLen), a);
m^.InfoStrings := a;
WITH m^ DO
IF (LONGCARD(MailID) >= LONGCARD(ptr^.mess.InfoStrings)) &
(LONGCARD(MailID) <= LONGCARD(ptr^.mess.InfoStrings)+LONG(ptr^.mess.infoLen)) THEN
MailID := ADDRESS(LONGCARD(MailID)-LONGCARD(ptr^.mess.InfoStrings)+LONGCARD(a));
ELSE
MailID := ADDRESS(0);
END;
IF (LONGCARD(Betreff) >= LONGCARD(ptr^.mess.InfoStrings)) &
(LONGCARD(Betreff) <= LONGCARD(ptr^.mess.InfoStrings)+LONG(ptr^.mess.infoLen)) THEN
Betreff := ADDRESS(LONGCARD(Betreff)-LONGCARD(ptr^.mess.InfoStrings)+LONGCARD(a));
ELSE
Betreff := ADDRESS(0);
END;
IF (LONGCARD(Absender) >= LONGCARD(ptr^.mess.InfoStrings)) &
(LONGCARD(Absender) <= LONGCARD(ptr^.mess.InfoStrings)+LONG(ptr^.mess.infoLen)) THEN
Absender := ADDRESS(LONGCARD(Absender)-LONGCARD(ptr^.mess.InfoStrings)+LONGCARD(a));
ELSE
Absender := ADDRESS(0);
END;
IF (LONGCARD(Empfaenger) >= LONGCARD(ptr^.mess.InfoStrings)) &
(LONGCARD(Empfaenger) <= LONGCARD(ptr^.mess.InfoStrings)+LONG(ptr^.mess.infoLen)) THEN
Empfaenger := ADDRESS(LONGCARD(Empfaenger)-LONGCARD(ptr^.mess.InfoStrings)+LONGCARD(a));
ELSE
Empfaenger := ADDRESS(0);
END;
IF (LONGCARD(mid) >= LONGCARD(ptr^.mess.InfoStrings)) &
(LONGCARD(mid) <= LONGCARD(ptr^.mess.InfoStrings)+LONG(ptr^.mess.infoLen)) THEN
mid := ADDRESS(LONGCARD(mid)-LONGCARD(ptr^.mess.InfoStrings)+LONGCARD(a));
ELSE
mid := ADDRESS(0);
END;
IF (LONGCARD(rid) >= LONGCARD(ptr^.mess.InfoStrings)) &
(LONGCARD(rid) <= LONGCARD(ptr^.mess.InfoStrings)+LONG(ptr^.mess.infoLen)) THEN
rid := ADDRESS(LONGCARD(rid)-LONGCARD(ptr^.mess.InfoStrings)+LONGCARD(a));
ELSE
rid := ADDRESS(0);
END;
IF (LONGCARD(box) >= LONGCARD(ptr^.mess.InfoStrings)) &
(LONGCARD(box) <= LONGCARD(ptr^.mess.InfoStrings)+LONG(ptr^.mess.infoLen)) THEN
box := ADDRESS(LONGCARD(box)-LONGCARD(ptr^.mess.InfoStrings)+LONGCARD(a));
ELSE
box := ADDRESS(0);
END;
IF (LONGCARD(name) >= LONGCARD(ptr^.mess.InfoStrings)) &
(LONGCARD(name) <= LONGCARD(ptr^.mess.InfoStrings)+LONG(ptr^.mess.infoLen)) THEN
name := ADDRESS(LONGCARD(name)-LONGCARD(ptr^.mess.InfoStrings)+LONGCARD(a));
ELSE
name := ADDRESS(0);
END;
IF (LONGCARD(gate) >= LONGCARD(ptr^.mess.InfoStrings)) &
(LONGCARD(gate) <= LONGCARD(ptr^.mess.InfoStrings)+LONG(ptr^.mess.infoLen)) THEN
gate := ADDRESS(LONGCARD(gate)-LONGCARD(ptr^.mess.InfoStrings)+LONGCARD(a));
ELSE
gate := ADDRESS(0);
END;
IF (LONGCARD(mime) >= LONGCARD(ptr^.mess.InfoStrings)) &
(LONGCARD(mime) <= LONGCARD(ptr^.mess.InfoStrings)+LONG(ptr^.mess.infoLen)) THEN
mime := ADDRESS(LONGCARD(mime)-LONGCARD(ptr^.mess.InfoStrings)+LONGCARD(a));
ELSE
mime := ADDRESS(0);
END;
END;
a := a + LONG(m^.infoLen);
IF ODD(LONGCARD(a)) THEN INC(a) END;
IF LONG(ptr^.mess.textLen) <= amount - (LONGCARD(a)-LONGCARD(adr)) THEN
data.ReadText(ptr^.handle^.Zugriff, ptr^.mess.MailNr, a);
IF data.error # data.noError THEN RETURN FALSE END;
END;
m^.Text := a;
RETURN TRUE;
ELSE
RETURN FALSE;
END;
ELSE
RETURN FALSE;
END;
END getInfo;
*)
PROCEDURE getBasicInfo(win : INTEGER; VAR group, mess: CARDINAL; storageAmount : LONGCARD):BOOLEAN;
(* Feststellen, welche Msg welcher Gruppe im bergebenen Fenster dargestellt wird. *)
(* In StorageAmount wird zurckgegeben, wieviel Speicher mal bentigt, um die *)
(* Informationen, die zu dieser Msg gehren, zu speichern. *)
VAR ptr : oneWindowPtr;
BEGIN
IF handlePool.FindEntry(ADR(win), FindWinCond, windows, ptr) THEN
group := ptr^.mess.Gruppe;
mess := ptr^.mess.MailNr;
storageAmount := TSIZE(data.MessageType) + LONG(ptr^.mess.textLen) + LONG(ptr^.mess.infoLen) + 200;
RETURN TRUE;
ELSE
RETURN FALSE;
END;
END getBasicInfo;
PROCEDURE grinOnlyOneWind (VAR wdw: INTEGER): BOOLEAN;
(* Wenn nur ein grin-Window offen ist, bekommt man TRUE zurck und
* das wdw-Handle auch direkt
*)
VAR p : oneWindowPtr;
BEGIN
wdw := -1;
IF Lists.NoOfEntries (windows) = 1
THEN
Lists.ResetList(windows);
p := Lists.NextEntry (windows);
IF p # NIL THEN
wdw := p^.win;
RETURN TRUE;
END;
END;
RETURN FALSE;
END grinOnlyOneWind;
(*$Z+*)
PROCEDURE testGrinWdw (wdw: INTEGER) : BOOLEAN;
VAR ptr : oneWindowPtr;
res: BOOLEAN;
BEGIN
res := handlePool.FindEntry(ADR(wdw), FindWinCond, windows, ptr);
RETURN res;
END testGrinWdw;
(*$Z=*)
PROCEDURE GetGrinTopWdw (VAR wdw: INTEGER);
(* Liefert das oberste Anzeigefenster zurck *)
BEGIN
wdw := WdwManager.FindSpecialTop (testGrinWdw);
END GetGrinTopWdw;
BEGIN
Lists.CreateList(windows, v.bool);
globalNumber := -1;
isInSearch := FALSE;
END grin.